Skip to content

Commit

Permalink
feat: ✨ 新增mobx-react-lite中observer与Observer使用与优化
Browse files Browse the repository at this point in the history
  • Loading branch information
guokaigdg committed Apr 13, 2023
1 parent ce83b22 commit fe5620b
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/components/Card/index.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.cp-card {
display: flex;
width: 100%;
padding: 1.5rem;
background-color: #393e46;
border-radius: 1rem;
Expand Down
2 changes: 2 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export {default as Button} from './Button';
export {default as Card} from './Card';
5 changes: 5 additions & 0 deletions src/router/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {Navigate, RouteObject} from 'react-router-dom';
const Home = SuspenseLazy(() => import(/* webpackChunkName:"" */ '@/view/Home'));
const HomeOne = SuspenseLazy(() => import(/* webpackChunkName:"homeOne" */ '@/view/Home/HomeOne'));
const HomeTwo = SuspenseLazy(() => import(/* webpackChunkName:"homeTwo" */ '@/view/Home/HomeTwo'));
const HomeThree = SuspenseLazy(() => import(/* webpackChunkName:"HomeThree" */ '@/view/Home/HomeThree'));
const Dashboard = SuspenseLazy(() => import(/* webpackChunkName:"dashboard" */ '@/view/Dashboard'));
const About = SuspenseLazy(() => import(/* webpackChunkName:"about" */ '@/view/About'));

Expand All @@ -29,6 +30,10 @@ const routes: RouteObject[] = [
{
path: 'two',
element: HomeTwo
},
{
path: 'three',
element: HomeThree
}
]
},
Expand Down
2 changes: 1 addition & 1 deletion src/styles/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

#root {
.app {
background: #e2e7e033;
background: #222;
}
}
68 changes: 68 additions & 0 deletions src/view/Home/HomeThree/components/ObserverComponents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import {Observer, useLocalObservable} from 'mobx-react-lite';
import {Button} from '@/components';
import {fetchPokemon} from '@/api';

const ObserverHoc = () => {
/**
* 关于 useLocalObservable
* 1. useLocalObservable 是 mobx-react-lite 提供的一个钩子函数,用于在 React 函数组件中创建局部的 observable 对象。
* 2. 可以使局部的状态更加清晰。
* 3. 代码更加简洁,避免在顶层创建全局的 observable 对象,提高了组件的可维护性和可重用性。
*/
const store = useLocalObservable(() => ({
count: 0,
loading: false,
list: [],
increment() {
this.count++;
},
decrement() {
this.count--;
},
async onFetchPokemon() {
this.loading = true;
const result: any = await fetchPokemon({limit: 100});
const {results} = result;
this.list = results;
this.loading = false;
},
onChange(item: {name: string; url: string}) {
// 点击某个条目时,修改该条目的 name,还记得 mobx 使用的是同一份数据吗,这里的更改能影响到列表的数据
item.name = '我被修改了';
}
}));

const ObserverItem = ({item}: {item: {name: string; url: string}}) => (
<Observer>
{() => {
// 只有修改数据渲染, 对于大量数据渲染有明显性能提升
console.log('render', item.name);
return <p onClick={() => store.onChange(item)}>{item.name}</p>;
}}
</Observer>
);

return (
<Observer>
{() => {
if (store.loading) {
return <p>loading...</p>;
}
return (
<div>
<h3>点击获取数据, 打开控制台, 点击某一项查看console.log(渲染情况)</h3>
<Button onClick={() => store.onFetchPokemon()}>获取数据Observer</Button>
<div>
{store.list?.map((item: {name: string; url: string}) => (
<ObserverItem key={item.url} item={item} />
))}
</div>
</div>
);
}}
</Observer>
);
};

export default ObserverHoc;
59 changes: 59 additions & 0 deletions src/view/Home/HomeThree/components/ObserverHoc.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react';
import {observer, useLocalObservable} from 'mobx-react-lite';
import {Button} from '@/components';
import {fetchPokemon} from '@/api';

const ObserverComponents = () => {
/**
* 关于 useLocalObservable
* 1. useLocalObservable 是 mobx-react-lite 提供的一个钩子函数,用于在 React 函数组件中创建局部的 observable 对象。
* 2. 可以使局部的状态更加清晰。
* 3. 代码更加简洁,避免在顶层创建全局的 observable 对象,提高了组件的可维护性和可重用性。
*/
const store = useLocalObservable(() => ({
count: 0,
loading: false,
list: [],
increment() {
this.count++;
},
decrement() {
this.count--;
},
async onFetchPokemon() {
this.loading = true;
const result: any = await fetchPokemon({limit: 100});
const {results} = result;
this.list = results;
this.loading = false;
},
onChange(item: {name: string; url: string}) {
// 点击某个条目时,修改该条目的 name,还记得 mobx 使用的是同一份数据吗,这里的更改能影响到列表的数据
item.name = '我被修改了';
}
}));

if (store.loading) {
return <p>loading...</p>;
}
console.log('Observe组件');

return (
<div>
<h3>点击获取数据, 打开控制台, 点击某一项查看console.log(渲染情况)</h3>
<Button onClick={() => store.onFetchPokemon()}>获取数据observer</Button>
<div>
{store.list?.map((item: {name: string; url: string}, index: number) => {
console.log('render', item.name);
return (
<p key={item.name + index} onClick={() => store.onChange(item)}>
{item.name}
</p>
);
})}
</div>
</div>
);
};

export default observer(ObserverComponents);
9 changes: 9 additions & 0 deletions src/view/Home/HomeThree/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.home-three-root{
display: flex;
flex: 1;
justify-content: space-between;
height: 100%;
padding: 30px;
overflow: scroll;
color: #7a7a7b;
}
16 changes: 16 additions & 0 deletions src/view/Home/HomeThree/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import ObserverHoc from './components/ObserverComponents';
import ObserverComponents from './components/ObserverHoc';

import './index.less';

const HomeThree = () => {
return (
<div className='home-three-root'>
<ObserverHoc />
<ObserverComponents />
</div>
);
};

export default HomeThree;

0 comments on commit fe5620b

Please sign in to comment.