外部函数中的 setState/use State react

IT技术 javascript reactjs react-native
2021-05-03 15:07:07

考虑这个伪代码:

component.js

...
import {someFunc} from "./common_functions.js"

export default class MyComp extends Component {
    constructor(props) {
        super(props);

    this.someFunc = someFunc.bind(this);

    this.state = {...};
    }

    _anotherFunc = () = > {
        ....
        this.someFunc();
    }

    render() {
        ...
    }
}

common_functions.js

export function someFunc() {
    if(this.state.whatever) {...}
    this.setState{...}
}

我如何将函数绑定someFunc()到 的上下文Component我在各种组件中使用它,因此将它们收集在一个文件中是有意义的。现在,我收到错误“无法读取任何未定义的内容”。上下文this未知...

4个回答

您不能在组件外部设置状态,因为它是组件的本地状态。如果您需要更新共享的状态,请创建一个存储(redux 存储)。

在您的情况下,您可以在一个地方定义 someFunction 并将特定状态变量或整个状态传递给它。在 someFunction 中完成后,返回修改后的状态并使用 setState 在您的组件中更新它。

export function someFunc(state) {
    if(state.whatever) {...}
    const newState = { ...state, newValue: whateverValue }
    return newState
}

_anotherFunc = () = > {
        ....
        const newState = this.someFunc(this.state);
       this.setState({newValue: newState});
    }

这不是 React 实践,它可能会导致很多问题/错误,但 js 允许这样做:

module A:

    export function your_external_func(thisObj, name, val) {
       thisObj.setSate((prevState) => { // prevState - previous state 
         // do something with prevState ...

         const newState = { // new state object
           someData: `This is updated data ${ val }`, 
           [name]: val,
         };
         return newState 
       });
    }

然后在你的 react-app module中使用它:

import { your_external_func } from '.../your_file_with_functions';

class YourReactComponent extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state={
      someName: '',
      someData: '',
    };
  }

  handleChange = (e) => {
    const { target } = event;
    const { name } = target;
    const value = target.type === 'checkbox' ? target.checked : target.value;

    your_external_func(this, name, value);
  }

  render() {
    return (<span>
      { this.state.someData }
      <br />
      <input 
        name='someName' 
        value={ this.state.someName }
        onChange={ this.handleChange }
      />
   </span>);
  }
}

这是一个愚蠢的例子:) 只是为了向您展示如何做到这一点

最好的办法显然是使用某种外部库来管理这个。正如其他人所建议的那样,Redux 和 MobX 对此有好处。使用高阶组件来包装所有其他组件也是一种选择。

但是,这是上述解决方案的替代解决方案:


您可以使用标准的 javascript 类(不是 React 组件)并传入this您从该类调用的函数。

这比较简单。我在下面创建了一个简单的示例,其中状态从另一个类的函数更改;看一看:

class MyApp extends React.Component {

  constructor() {
    super();
    this.state = {number: 1};
  }

  double = () => {
    Global.myFunc(this);
  }

  render() {
    return (
      <div>
        <p>{this.state.number}</p>
        <button onClick={this.double}>Double up!</button>
      </div>
    );
  }
}

class Global {
  static myFunc = (t) => {
    t.setState({number: t.state.number*2});
  }
}

ReactDOM.render(<MyApp />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"><div>

setState 有一种函数形式,甚至可以在组件之外使用。

这是可能的,因为 setState 的签名是:

* @param {object|function} partialState Next partial state or function to
*        produce next partial state to be merged with current state.
* @param {?function} callback Called after state is updated.

见丹的推文:https : //twitter.com/dan_abramov/status/824308413559668744