我有两个组件,它们使用HOC从上下文提供程序获取数据。
但是,当一个孩子更新提供者中的状态时,似乎并没有为所有使用HOC的组件更新,因此仍然显示旧值。
为什么会这样,或者我在这里做错了什么?如何获取所有组件中的更新值?
一个用于说明问题的简单示例的堆栈摘录:
const { Component } = React;
const { render } = ReactDOM;
let UserContext;
const { Provider, Consumer } = (UserContext = React.createContext());
class UserProvider extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "Colin",
setName: this.setName,
};
}
setName = (name) => {
this.setState({name});
}
render() {
return <Provider value={this.state}>{this.props.children}</Provider>;
}
}
const withUser = Component => props => (
<UserProvider>
<Consumer>{user => <Component {...user} {...props} />}</Consumer>
</UserProvider>
);
const TempA = ({name}) => {
return <h1>A: {name}</h1>
}
const TempB = ({name, setName}) => {
return (
<React.Fragment>
<h1>B: {name}</h1>
<button onClick={() => setName('Ricardo')}>change name</button>
</React.Fragment>
)
}
const A = withUser(TempA);
const B = withUser(TempB);
const App = () => {
return (
<React.Fragment>
<A />
<B />
</React.Fragment>
)
}
const AppToRender = withUser(App);
render(<AppToRender />, document.getElementById('root'));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
答案 0 :(得分:2)
您每次使用Provider
时都会创建一个新的withUser
。
如果您想在整个应用程序中使用同一用户,则可以将Provider
放在App
组件的顶部,而只需withUser
创建一个新的{{1 }}。
Consumer
const { Component } = React;
const { render } = ReactDOM;
const UserContext = React.createContext();
const { Provider, Consumer } = UserContext;
class UserProvider extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "Colin",
setName: this.setName,
};
}
setName = (name) => {
this.setState({name});
}
render() {
return <Provider value={this.state}>{this.props.children}</Provider>;
}
}
const withUser = Component => props => (
<Consumer>{user => <Component {...user} {...props} />}</Consumer>
);
const TempA = ({name}) => {
return <h1>A: {name}</h1>
}
const TempB = ({name, setName}) => {
return (
<React.Fragment>
<h1>B: {name}</h1>
<button onClick={() => setName('Ricardo')}>change name</button>
</React.Fragment>
)
}
const A = withUser(TempA);
const B = withUser(TempB);
const App = () => {
return (
<UserProvider>
<A />
<B />
</UserProvider>
)
}
render(<App />, document.getElementById('root'));