Реагируйте: Как я могу использовать моего потребителя внутри ComponentDidMount для изменения состояния?
Поэтому я использую контекст React, потому что я должен изменить состояние в противоположном направлении.
Например:
App.js (имеет состояние) <--- Мой компонент (изменяет состояние в App.js)
Я знаю, как это сделать, используя событие onClick. Тем не менее, я не понимаю, как это сделать в componentDidMount(). Я создал базовый пример, чтобы проиллюстрировать, чего я пытаюсь достичь:
MyComponent.js
import { MyConsumer } from '../App.js';
export default class MyComponent extends Component {
componentDidMount() {
// TRYING TO CHANGE STATE IN COMPONENTDIDMOUNT
<MyConsumer>
{({ actions }) => actions.setMyState(true)}
</MyConsumer>
}
render() {
return (
<SearchConsumer>
{({ actions }) => {
return (
<div onClick={() => actions.setMyState(true)}>
My content
</div>
)
}}
</SearchConsumer>
)
}
}
App.js
export const SearchContext = createContext();
export const SearchProvider = SearchContext.Provider;
export const SearchConsumer = SearchContext.Consumer;
class App extends Component {
constructor (props) {
super (props)
this.state = {
setMyState: 0,
}
}
render(){
return(
<SearchProvider value={
{
actions: {
setMyState: event => {
this.setState({ setMyState: 0 })
},
}
}
}>
<Switch>
<Route
exact path='/' render={(props) => <MyComponent />}
/>
</Switch>
</SearchProvider>
)
}
}
2 ответа
Если вы используете реагирование 16.6.0 или более поздней версии и используете только одного потребителя контекста, то самый простой подход - это использовать contextType
(обратите внимание, что это единственное, а не множественное число). Это заставит реакцию сделать значение доступным на this.context
, который затем можно использовать в хуках жизненного цикла. Например:
// In some other file:
export default MyContext = React.createContext();
// and in your component file
export default class MyComponent extends Component {
static contextType = MyContext;
componentDidMount() {
const { actions } = this.context;
actions.setMyState(true);
}
// ... etc
}
Если вы используете старую версию и не можете использовать contextType
или если вам нужно получить значения из нескольких контекстов, вам вместо этого нужно будет обернуть ваш компонент в другой компонент и передать контекст через опору.
// In some other file:
export default MyContext = React.createContext();
// and in your component file
class MyComponent extends Component {
static contextType = MyContext;
componentDidMount() {
const { actions } = this.props;
actions.setMyState(true);
}
// ... etc
}
export default props => (
<MyContext.Consumer>
{({ actions }) => (
<MyComponent actions={actions} {...props} />
)}
</MyContext.Consumer>
);
Я решил свою проблему с помощью идеи, полученной благодаря ответу Николас Тауэр. Вместо использования contextType в React я просто передал свои действия в качестве опоры в другом компоненте. Таким образом, я все еще мог бы использовать все, что есть у моего потребителя, если бы просто передавал это в качестве опоры.
class MyComponent extends Component {
componentDidMount() {
this.props.actions.setMyState(true);
}
// ... etc
}
export default class MyComponentTwo extends Component {
render(){
return(
<MyConsumer>
{({ actions }) => (
<MyComponent actions={actions}/>
)}
</MyConsumer>
)
}
);