在react中,组件间传值是一个非常重要的功能。react中组件拆分要合理,精细。所以组件拆分时,会把一个页面级组件分为容器组件和展示组件。
容器组件:只负责当前页面组件所需要的的所有数据以及业务逻辑。
展示组件:负责接收容器组件中的数据,并展示出来。
展示组件中有可以划分更详细的组件。
1.容器组件向展示组件传值:
在容器组件中,准备好要传的数据(函数+数据)。
render() {
return (
// 容器组件
<UIList list={this.state.list} data={this.state.data}
changeOrderDir={this.changeOrderDir}
changeOrderCol={this.changeOrderCol}
/>
);
}
在展示组件中接收调用。
展示组件一般使用函数组件:可以在函数中接收传过来的数据。
如果是类组件,需要使用this.props调用。
// 函数组件
const UIList = ({ changeOrderCol }) => (
<span onClick={ () => changeOrderCol("rate")}>评价</span>
);
// 类组件
class UIList extends React.Component {
render() {
return (
<span onClick={ () => this.props.changeOrderCol("rate")}>评价</span>
);
}
}
2.容器组件向展示组件的子组件传值:
容器组件需要向展示组件的子组件进行传值,当然也可以一层一层的传递,不过比较麻烦,如果数据更新,有可能会使无关的组件重新渲染。
这里,使用context上下文来存储容器组件的数据。数据的提供者叫做生产者,数据的使用方叫做消费者。
首先,我们需要在包含页面级组件的文件夹下新建一个context.js文件,其内容为:
import React from "react";
export default React.createContext();
在页面级组件的容器组件内导入context.js文件,并使用。
import Context from './context.js';
render() {
let contextValue = {
...this.state,
changeCategory: this.changeCategory,
avatar: this.findAvatar(this.state.activeId)
};
return (
<Context.Provider value={ contextValue }>
<UICategory />
</Context.Provider>
);
}
在需要的子组件中,导入context.js文件,并使用。
import Context from './context.js';
<Context.Consumer>
{({listSub, avatar}) => ()}
</Context.Consumer>
当子组件是函数组件时:
import React, { useContext } from "react";
import UI from './UI.jsx';
import Context from '../context.js';
const ListOrder = () => {
// 从Context上下文中拿去数据
const { orderDir, orderCol, setOrderCol, setOrderDir } = useContext(Context);
let UIProps = { orderDir, orderCol, setOrderCol, setOrderDir };
return (
<UI {...UIProps} />
);
};
export default ListOrder;
通过组件间的传参,在子组件中获取容器组件的数据,利于组件的拆分和代码的维护。