如何从任何组件外部调用React的setState函数,例如实用程序函数?

时间:2018-08-01 09:46:43

标签: javascript reactjs

我有一个应用程序,我想在其中将读写操作移至实用程序文件,即远离组件。我正在尝试这样做。

component.js

import { saveData } from './utils/fileSave.js';

class App extends Component {
    saveContent() {
        saveData(this.setState, data);
    }
    ...
}

utils / fileSave.js

const saveData = (setState, data) => {
    setState(data);
}

但是,这会导致错误,提示“ TypeError:无法读取未定义的属性'updater'”

不确定这是否是正确的解决方法。

4 个答案:

答案 0 :(得分:2)

需要将this绑定到setState

 saveData(this.setState.bind(this), data);

工作codesandbox demo

答案 1 :(得分:1)

在将setState传递给外部函数之前,您似乎需要将其绑定。

saveData(this.setState.bind(this), data);

答案 2 :(得分:1)

将依赖于上下文(组件实例)的方法提取到实用程序功能不是一个好主意,主要是因为这需要采取其他措施才能使它们起作用。

由于this.setState作为回调传递,因此应将其绑定到适当的上下文:

saveData(this.setState.bind(this), data);

或者将效用函数定义为常规函数,并在适当的上下文中调用

function saveData(data) {
    this.setState(data);
}

class App extends Component {
    saveContent() {
        saveData.call(this, data);
    }
    ...
}

在这种情况下,继承是更可取的,因为它可以自然地获取适当的上下文。 saveData可以通过mixin重复使用。

它可以直接分配给类原型:

function saveData(data) {
    this.setState(data);
}

class App extends Component {
    // saveData = saveData
    // is less efficient but also a correct way to do this
    saveContent() {
        this.saveData(data);
    }
    ...
}
App.prototype.saveData = saveData;

或通过装饰器应用

function saveData(target) {
    return class extends target {
        saveData(data) {
            this.setState(data);
        }
    }
}


@saveData
class App extends Component {
    saveContent() {
        this.saveData(data);
    }
    ...
}

答案 3 :(得分:0)

用arrow函数替换bind函数将使其像回调一样工作。

saveData((newState) => this.setState(newState), data);