React的核心特征是“数据驱动视图”,也就是React 的视图会随着数据的变化而变化。
一、基于 props 的单向数据流
单向数据流,指的就是当前组件的 state 以 props 的形式流动时,只能流向组件树中比自己层级更低的组件。 比如在父-子组件这种嵌套关系中,只能由父组件传 props 给子组件,而不能反过来。
React 数据流管理方案:
- 使用基于 Props 的单向数据流串联父子、兄弟组件;
- 利用“发布-订阅”模式驱动 React 数据在任意组件间流动。
- 使用 Context API 维护全局状态
- 使用第三方数据流Redux
1、props chidren模式
<Container>
<Children>
</Container>
function Container(props){
return props.children
}
作用:
- 可以根据需要控制 Chidren 是否渲染。
- Container 可以用 React.cloneElement 强化 props (混入新的 props ),或者修改 Chidren 的子元素。
2、render props模式
<Container>
{ (ContainerProps)=> <Children {...ContainerProps} /> }
</Container>
function Container(props) {
const ContainerProps = {
name: 'alien',
mes:'let us learn react'
}
return props.children(ContainerProps)
}
作用:
- 根据需要控制 Chidren 渲染与否。
- 可以将需要传给 Children 的 props 直接通过函数参数的方式传递给执行函数 children 。
3、混合模式
<Container>
<Children />
{ (ContainerProps)=> <Children {...ContainerProps} name={'haha'} /> }
</Container>
这种情况需要先遍历 children ,判断 children 元素类型:
- 针对 element 节点,通过 cloneElement 混入 props ;
- 针对函数,直接传递参数,执行函数。
const Children = (props)=> (<div>
<div>hello, my name is { props.name } </div>
<div> { props.mes } </div>
</div>)
function Container(props) {
const ContainerProps = {
name: 'alien',
mes:'let us learn react'
}
return props.children.map(item=>{
if(React.isValidElement(item)){ // 判断是 react elment 混入 props
return React.cloneElement(item,{ ...ContainerProps },item.props.children)
}else if(typeof item === 'function'){
return item(ContainerProps)
}else return null
})
}
const Index = ()=>{
return <Container>
<Children />
{ (ContainerProps)=> <Children {...ContainerProps} name={'haha'} /> }
</Container>
}
二、知识点梳理
具体查看链接:https://www.yuque.com/linhe-8mnf5/fxyxkm/cghcta 组件通信这一块。
三、Redux
在 Redux 的整个工作过程中,数据流是严格单向的。
如果你想对数据进行修改,只有一种途径:派发 action。action 会被 reducer 读取,进而根据 action 内容的不同对数据进行修改、生成新的 state(状态),这个新的 state 会更新到 store 对象里,进而驱动视图层面做出对应的改变。
对于组件来说,任何组件都可以通过约定的方式从 store 读取到全局的状态,任何组件也都可以通过合理地派发 action 来修改全局的状态。Redux 通过提供一个统一的状态容器,使得数据能够自由而有序地在任意组件之间穿梭。
1. 使用 createStore 来完成 store 对象的创建
// 引入 redux
import { createStore } from 'redux'
// 创建 store
const store = createStore(
reducer,
initial_state,
applyMiddleware(middleware1, middleware2, ...)
);
2. reducer 的作用是将新的 state 返回给 store
const reducer = (state, action) => {
// 此处是各种样的 state处理逻辑
return new_state
}
3. action 的作用是通知 reducer “让改变发生”
const action = {
type: "ADD_ITEM",
payload: '<li>text</li>'
}
4. 派发 action,靠的是 dispatch
import { createStore } from 'redux'
// 创建 reducer
const reducer = (state, action) => {
// 此处是各种样的 state处理逻辑
return new_state
}
// 基于 reducer 创建 state
const store = createStore(reducer)
// 创建一个 action,这个 action 用 “ADD_ITEM” 来标识
const action = {
type: "ADD_ITEM",
payload: '<li>text</li>'
}
// 使用 dispatch 派发 action,action 会进入到 reducer 里触发对应的更新
store.dispatch(action)
四、其他数据流通信实践
父-子:略
context:https://www.yuque.com/linhe-8mnf5/fxyxkm/bhg5gk#Context
发布-订阅:https://www.yuque.com/linhe-8mnf5/fxyxkm/fhe89i