React Context API - могут ли дети / потребители требовать, чтобы поставщик изменил значение?
Ранее я использовал Redux, и на этот раз я хочу реализовать Context API. Я очень хочу сделать то, что описано в React Context API - Как получить ссылку на объект состояния в поставщике для условного метода - однако, я хочу, чтобы функция "изменения" была более общей - она изначально выглядит так:
class ProviderComp extends Component{
state={
name: "Gary",
age: 20,
color: "Red",
changeMind: ()=>{
if(this.state.color === "Red"){
this.setState({
name: "Tony",
age: 35,
color: "Blue"
})
}
if(this.state.color === "Blue"){
this.setState({
name: "Gary",
age: 20,
color: "Red"
})
}
}
}
но вместо "changeMind()" я хотел бы изменить (prop, val), чтобы вызывать:
change("name","Bob")
изменит state.name на Bob
change("age", 30)
изменил бы state.age до 30 и т. д.
Это возможно? Я пытаюсь сделать что-то аналогичное тому, как ребенок в Redux отправляет запрос на изменение, а родительский редуктор получает запрос и обновляет его соответственно.
Я, вероятно, неправильно думаю о контексте, так как я не просто предоставляю исходные данные, а затем потребляю нисходящие потоки, я пытаюсь заставить нижестоящих потребителей отправлять обратные запросы поставщику, чтобы они могли что-то изменить - очень открыты для получения лучшего образования. думать!
2 ответа
Чтобы изменить значение провайдера, <Provider>
должны быть перерисованы. Итак, речь идет о создании компонента, в котором размещается поставщик, для хранения и обновления состояния:
class ProviderComp extends Component {
state = {
change: (key, val) => this.setState({ [key]: val }),
...
};
render() {
return <SomeContext.Provider value={this.state}>...</SomeContext.Provider>
}
}
Да, просто передайте функцию изменения в значение контекста. В вашем компоненте, который содержит провайдер контекста
changeMind = mind => this.setState({mind})
render() {
<Context.Provider value={{mind : this.state.mind, changeMind : this.changeMind}}>
</Context.Provider>
}
Затем в компоненте, который имеет потребителя, вы можете вызвать context.changeMind
что приведет к изменению значения поставщика, например
<Context.Consumer>
{
contextValue => (<button onClick={contextValue.changeMind}>Change</button>)
}
</Context.Consumer>