代码之家  ›  专栏  ›  技术社区  ›  Shawn Matthews

React-能否从外部函数更新未声明的容器状态?

  •  3
  • Shawn Matthews  · 技术社区  · 6 年前

    在未声明库的示例中,它们通过与订阅到容器的jsx按钮交互来更新容器中的状态。

    import React from 'react';
    import { render } from 'react-dom';
    import { Provider, Subscribe, Container } from 'unstated';
    
    type CounterState = {
      count: number
    };
    
    class CounterContainer extends Container<CounterState> {
      state = {
        count: 0
      };
    
      increment() {
        this.setState({ count: this.state.count + 1 });
      }
    
      decrement() {
        this.setState({ count: this.state.count - 1 });
      }
    }
    
    function Counter() {
      return (
        <Subscribe to={[CounterContainer]}>
          {counter => (
            <div>
              <button onClick={() => counter.decrement()}>-</button>
              <span>{counter.state.count}</span>
              <button onClick={() => counter.increment()}>+</button>
            </div>
          )}
        </Subscribe>
      );
    }
    
    render(
      <Provider>
        <Counter />
      </Provider>,
      document.getElementById('root')
    );
    

    有没有办法从容器外组件中的函数更新容器内的状态?例如,如果我想在一个承诺的返回过程中更新state,我该怎么做呢。伪码

    login = () => {
        let url = baseURL + '/user/login?_format=json';  
    
        let data = {
          "name": this.state.email,  
          "pass": this.state.password
        };
    
    
    
            axios({
              url,
              method: "POST",
              headers: {
                'Accept':  'application/json',
                'Content-Type': 'application/json',
              },
              withCredentials: true,
              credentials: 'same-origin', 
              data,
              })
              .then(function(result) {
                console.log('result:', result);
                    SET STATE HERE!!!!!!!
    counter.increment()
    
                  })
              .catch(error => console.log('error:', error));
          };
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   Estus Flask    6 年前

    这个问题并不是特定于Unstated,这也适用于使用render prop模式的React上下文API。

    问题在于 login

    它可以公开承诺,或接受回调,或两者兼有:

    login = async (cb) => {
      ...    
      return axios(...)
      .then(function(result) {
        if (cb)
          cb(result);
    
        return result;
      })
      .catch(error => console.log('error:', error));
    }
    

    <button onClick={() => login(() => counter.decrement())}>-</button>
    

    或:

    <button onClick={async () => { await login(); counter.decrement(); }}>-</button>
    

    也有可能 接受 counter 作为一个论点,但这将耦合它的实现,这是不必要的。

        2
  •  1
  •   Sushanth --    6 年前

    <Login upParentCounter={this.increment}/>
    

    在登录组件中

    this.props.upParentCounter()
    

    Dealing with Nested React Components' State Changes