如何注入改变组件状态的函数?

时间:2018-08-17 19:37:22

标签: javascript reactjs conventions

我想将某些功能保留在组件之外,以便于测试。但是,我无法使用这些功能更改状态,因为它们无法直接引用组件的状态。

因此,我目前有一个hacky解决方案,可以将函数设置为变量,然后调用this.setState。有更好的约定/更有效的方法来做到这一点吗?

Tester.js中的示例功能代码:

const tester = () => {
  return 'new data';
}

export default tester;

App.js中的示例组件代码(不带导入):

class App extends Component {
    constructor() {
        super();
        this.state = {
            data: ''
        }
    }

    componentDidMount(){
        let newData = tester();
        this.setState({ data: newData })
    }

    render() {
        return(
            <div>{this.state.data}</div>
        )
    }
}

2 个答案:

答案 0 :(得分:1)

您可以像这样绑定您的测试器功能(此方法不适用于箭头功能):

const rp = require('request-promise');
const cheerio = require('cheerio');
var cookiejar = rp.jar();
var actualpage = 1;
var baseuri = 'https://www.website.page=' + actualpage;
var options = {
  uri: baseuri,
  headers: {
    'Host': 'www.website.com',
    'Connection': 'keep-alive'
  },
  jar: cookiejar,
  transform: function(body) {
    return cheerio.load(body);
  }
};

goforit()

function goforit() {
  actualpage = actualpage + 1
  baseuri = 'https://www.website.com' + actualpage;

  setTimeout(function() {
    rp(options)
      .then(($) => {
        var arr = 0
        arr = $('.bt__media__content p')

        var fruits = $('.bt__ment p');
        fruits.each(function(i, elem) {
          console.log(fruits[i].children[0].attribs)
        });
        goforit()

      })
      .catch((err) => {
        console.log(err);
      });

  }, 3000);
}

但是我更喜欢一种更清洁的方法,在这种方法中,您不需要您的函数来访问 this (也可以使用箭头功能):

function tester() {
  this.setState({ data: 'new Data' });
}

class App extends Component {
  constructor() {
    super();
    this.state = {
      data: '',
    };
    this.tester = tester.bind(this);
  }

  componentDidMount() {
    this.tester();
  }

  render() {
    return (
      <div>{this.state.data}</div>
    );
  }
}

答案 1 :(得分:0)

You can pass a function to setState(),它将返回一个代表对象新状态的新对象。因此,您可以这样做:

const tester = (previousState, props) => {
  return {
    ...previousState,
    data: 'new data',
  };
}

class App extends Component {
    constructor() {
        super();
        this.state = {
            data: ''
        }
    }

    componentDidMount(){
        this.setState(tester)
    }

    render() {
        return(
            <div>{this.state.data}</div>
        )
    }
}

原因是您现在可以在tester函数中访问组件的先前状态和道具。

如果您只需要访问应用内不变的 static 占位符值(例如Lorem Ipsum或其他内容),则只需将数据导出为JSON对象并按以下方式使用它即可:

// testData.js
export const testData = {
  foo: "bar",
  baz: 7,
};

...

// In your app.jsx file
import testData from "./testData.js";

const qux = testData.foo; // "bar"

etc.