Реагируйте: Как я могу использовать моего потребителя внутри ComponentDidMount для изменения состояния? - PullRequest
0 голосов
/ 18 февраля 2019

Так что я использую контекст React, потому что я должен изменить состояние в противоположном направлении.Например: App.js (имеет состояние) <--- </strong> Мой компонент (изменяет состояние в 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 ]

0 голосов
/ 19 февраля 2019

Я исправил свою проблему с помощью идеи, полученной благодаря ответу Николас Тауэр.Вместо использования 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>
    )
  }
);
0 голосов
/ 18 февраля 2019

Если вы используете response 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>
);
...