【问题标题】:React - Setting component state using a function outside of state, is it wrong?React - 使用状态之外的函数设置组件状态,这是错误的吗?
【发布时间】:2018-10-09 23:10:51
【问题描述】:

在 React 组件之外的函数中使用 setState 有错吗?

例子:

// myFunction.js
function myFunction() {
  ...
  this.setState({ ... })
}

// App.js
import myFunction from './myFunction

class App extends Component {
  constructor() {
    super()
    this.myFunction = myFunction.bind(this)
  }

  ...
}

【问题讨论】:

  • 没错。您实际上是在创建一个 mixin 函数。
  • @corasan 以这种方式编写的代码真的会为你运行吗?
  • @Colin 是的,确实如此,完美运行

标签: javascript reactjs react-native ecmascript-6


【解决方案1】:

它看起来像一个等待发生的错误......如果你想使用外部函数来设置状态,你可以使用 React 提供的替代语法:

this.setState((prevState, props)  => {
  return updatedState; //can be a partial state, like in the regular setState
});

这个回调可以很容易地被提取到一个外部函数中并且保证可以工作

【讨论】:

    【解决方案2】:

    所以这样做的唯一原因是如果您要减少重复代码,例如两个组件在调用this.setState 之前使用相同的逻辑,或者如果您想通过单独的纯函数进行测试来简化测试。出于这个原因,我建议不要在您的外部函数中调用 this.setState,而是返回您需要的对象,以便您可以在其上调用 this.setState

    function calculateSomeState(data) {
      // ...
      return { updated: data };
    }
    
    class MyComponent extends React.Component {
        constructor(props) {
          super(props)
          this.state = calculateSomeState(props.data);
        }
    
        handleChange = (e) => {
            const value = e.target.value;
            this.setState(calculateSomeState({ ...props.data, value }));
        }
    }
    

    【讨论】:

      【解决方案3】:

      没错,该函数永远不会在组件外部调用。这是一种混合技术。 bind 不需要,只要该函数不用作回调。在这种情况下,myFunction 在所有实例中都是相同的,更有效的方法是:

      class App extends Component {}
      App.prototype.myFunction = myFunction;
      

      【讨论】:

      • "只要函数不用作回调,就不需要绑定。" ——你能解释一下吗?
      • 如果作为回调传递,则应该绑定,例如onClick={this.myFunction}。如果使用正确的上下文(如this.myFunction())调用它,则不应绑定它。你在哪里使用这个功能?
      【解决方案4】:

      我不确定您的绑定方式是否真的有效。你可以这样做:

      export const getName = (klass) => {
        klass.setState({ name: 'Colin'})
      }
      

      然后

      class App extends Component {
        state = {
          name: 'React'
        };
      
        handleClick = () => {
          getName(this);
        }
      
        render() {
          return (
            <div>
              <p>{this.state.name}</p>
              <button onClick={this.handleClick}>change name</button>
            </div>
          );
        }
      }
      

      工作示例here

      【讨论】:

      • 是的,它在示例中的工作方式,我只是想知道它是否是反模式并且不应该这样做,例如对组件的负面影响等。
      • 赞成,因为采用了新方法,但我和操作员有同样的问题。应该鼓励这种写作方式吗?我猜不是。
      • 就我个人而言,我不会使用它,而且我也从未见过它在任何地方使用过。
      猜你喜欢
      • 2021-10-31
      • 2018-04-10
      • 1970-01-01
      • 2016-09-27
      • 2017-10-03
      • 2019-02-17
      • 2019-08-10
      • 2017-08-17
      • 1970-01-01
      相关资源
      最近更新 更多