React - 您可以从外部函数更新未声明的容器状态吗? [英] React - Can you update an Unstated container state from an external function?

查看:32
本文介绍了React - 您可以从外部函数更新未声明的容器状态吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Unstated 库的示例中,它们通过与订阅容器的 jsx 按钮交互来更新容器内的状态.

从'react'导入React;从'react-dom'导入{渲染};import { Provider, Subscribe, Container } from 'unstated';类型 CounterState = {计数:数量};类 CounterContainer 扩展 Container<CounterState>{状态 = {计数:0};增量() {this.setState({ count: this.state.count + 1 });}递减(){this.setState({ count: this.state.count - 1 });}}函数计数器(){返回 (<订阅={[CounterContainer]}>{计数器=>(<div><button onClick={() =>counter.decrement()}>-</button><span>{counter.state.count}</span><button onClick={() =>counter.increment()}>+

)}</订阅>);}使成为(<提供者><计数器/></提供者>,document.getElementById('root'));

有没有办法从容器外的组件中的函数更新容器内的状态?因此,例如,如果我想在返回承诺期间更新状态,我将如何进行.伪代码

登录 = () =>{让 url = baseURL + '/user/login?_format=json';让数据 = {名称":this.state.email,通行证":this.state.password};轴({网址,方法:POST",标题:{'接受':'应用程序/json','内容类型':'应用程序/json',},withCredentials: 真,凭据:'同源',数据,}).then(函数(结果){console.log('result:', result);在这里设置状态!!!!!!!计数器.增量()}).catch(error => console.log('error:', error));};

解决方案

该问题不是 Unstated 特有的,这也适用于使用 render prop 模式的 React 上下文 API.

login 的问题在于其控制流程存在缺陷.它无法有效地捕获错误,因为它会抑制它们.并且它把promise封装在里面,这是一个错误,阻止它被正确测试,对于初学者来说

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

login = async (cb) =>{...返回 axios(...).then(函数(结果){如果 (cb)CB(结果);返回结果;}).catch(error => console.log('error:', error));}

可以用作:

或者:

也可以让 login 接受 counter 作为参数,但这会使其与不必要的实现耦合.

In the example from the Unstated library they update state within a container by interacting with a jsx button that is subscribed to the container.

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')
);

Is there a way to update the state within the container from a function in a component outside of the Container? So for instance if I want up to update state during the return of a promise how would I go about doing so. Pseudo code

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));
      };

解决方案

The problem isn't specific to Unstated, this would apply to React context API that uses render prop pattern, too.

The problem with login is that its control flow is flawed. It isn't be able to efficiently catch errors because it suppresses them. And it encapsulates the promise inside, which is a mistake that prevents it from being properly tested, for starters

It can expose a promise, or accept a callback, or both:

login = async (cb) => {
  ...    
  return axios(...)
  .then(function(result) {
    if (cb)
      cb(result);

    return result;
  })
  .catch(error => console.log('error:', error));
}

Can be used as:

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

Or:

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

It's also possible to make login accept counter as an argument but this would couple it to implementation which is unnecessary.

这篇关于React - 您可以从外部函数更新未声明的容器状态吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆