1.状态提升
将子组件共享的数据,提升到父组件中,作为props传给子组件,已达到数据共享。
- 当你想要整合两个组件时,将它们的 state 移动到共同的父组件中。
- 然后在父组件中通过 props 把信息传递下去。
- 最后,向下传递事件处理程序,以便子组件可以改变父组件的 state 。
- 考虑该将组件视为“受控”(由 prop 驱动)或是“不受控”(由 state 驱动)是十分有益的。
2.使用react自带的context
- Context 的使用场景
Context 不局限于静态值。如果你在下一次渲染时传递不同的值,React 将会更新读取它的所有下层组件!这就是 context 经常和
state 结合使用的原因。
一般而言,如果树中不同部分的远距离组件需要某些信息,context 将会对你大有帮助。
- 主题: 如果你的应用允许用户更改其外观(例如暗夜模式),你可以在应用顶层放一个 context provider,并在需要调整其外观的组件中使用该 context。
- 用户数据: 许多组件可能需要知道当前登录的用户信息。将它放到 context 中可以方便地在树中的任何位置读取它。某些应用还允许你同时操作多个账户(例如,以不同用户的身份发表评论)。在这些情况下,将 UI 的一部分包裹到具有不同账户数据的 provider 中会很方便。
- 路由: 大多数路由解决方案在其内部使用 context 来保存当前路由。这就是每个链接“知道”它是否处于活动状态的方式。如果你创建自己的路由库,你可能也会这么做。
- 状态管理: 随着你的应用的增长,最终在靠近应用顶部的位置可能会有很多 state。许多遥远的下层组件可能想要修改它们。通常 将 reducer 与 context 搭配使用来管理复杂的状态并将其传递给深层的组件来避免过多的麻烦。
- context的使用方法
1.创建:
通过 export const MyContext = createContext(defaultValue) 创建并导出context。
2. 使用: 在子组件中引入使用。
在无论层级多深的任何子组件中,把 context 传递给 useContext(MyContext) Hook来读取它。
4. 提供: 在父组件中给context赋值
在父组件中把 children 包在 <MyContext.Provider value={…}> 中来提供 context。
3.结合Reducer使用,效果更佳!
reducer一个函数,你可以把对state状态更改的逻辑放在里面。在组件中只是触发变更,在reducer函数中进行变更。很像store中的mutation对吧!
- 什么是reducer,以及如何使用?
1.编写一个 Reducer 函数 :
接受两个参数,分别为当前 state【当前状态】 和 action 对象,并且返回的是更新后的 state:
function tasksReducer(tasks, action) {
switch (action.type) {
case 'added': {
return [
...tasks,
{
id: action.id,
text: action.text,
done: false,
},
];
},
//……
default: {
throw Error('未知 action: ' + action.type);
}
}
}
- 使用:
//1.
import { useReducer } from 'react';
import {tasksReducer} from './tasksReducer.js'
//2.initialTasks,tasks的初始值
const [tasks, dispatch] = useReducer(tasksReducer, initialTasks);
//3.通过触发dispatch,进行task值的变更,而非使用useState.
function handleAddTask(text){
distpatch({
type:'added',//用于reducer函数中判断走那个处理分支,必传
id,
text//剩余参数根据逻辑需要传递,非必传
})
- 结合使用 Reducer 和 Context ,实现最佳效果!
以上是官网例子,先忽略具体实现一起梳理一下思路。
- 使用context的原理就是在顶级传递参数,那么我们一定是在顶级父级里传递变量
- 这个组件的本质是什么?对于数组的增删查改–》在任何组件内部都可以直接操作数组
- 我们可以对那些东西进行“公共化”?数组列表和对数组列表操作的方法。
因此:
我们在父容器中创建并初始化:数组值、操作数组的方法。
在子组件中利用reducer改变数组值。