如何在 React 组件的 render() 中使用回调

How to use a callback in a render() of React component

我想使用对集合进行计数的服务器方法的结果,以在 React 组件的渲染方法中显示它。我知道我必须从回调函数中执行此操作,但它对我不起作用。

服务器方法:

export const analysis = new ValidatedMethod({
  name: "analysis",
  validate: new SimpleSchema({
    codigo: {
      type: String
    },
    rta: {
      type: String
    }
  }).validator(),
  run(one) {
    const rta = Respuesta.find({
      codigo: one.codigo,
      rtatexto: one.rta,
      activo: true
    }).count();
    console.log(rta);
    return Number(rta);
  }
});

客户来电:

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

  render() {
    const one = { codigo: this.props.codigo, rta: this.props.opcion };
    const rta = analysis.call(one, (err, res) => {
      return (
        <Table.Row>
          <Table.Cell> {this.props.opcion} </Table.Cell>
          <Table.Cell> {res} </Table.Cell>
        </Table.Row>
      );
    });
  }
}

如何在组件的渲染方法中使用 res 的值?

异步函数

在我回答这个问题之前,了解 JavaScript.

中同步函数和异步函数的区别很重要

因此,如果您不熟悉 JavaScript 或异步行为,我建议您阅读 this excellent answer and explanation about the topic

问题的解释

这里的问题是 React 的 render() 方法是一个同步方法,这意味着 React 需要一个同步的 return 值 jsx (或者 React.Element 就此而言).

对于 React,您当前的渲染函数实际上 return 什么都没有或 undefined,因为您没有同步 return 语句。所以什么都不会渲染。

React 无法知道您的回调何时被调用或者它 return 是什么,因为它完全是在 Reacts 上下文之外执行的。

问题的解决方案

这里的方法是使用 Reacts state,这正是这种情况。

通过使用状态和方法 setState(),您可以在 API 的响应传送数据后立即异步触发渲染方法再次调用。此外,使用 this.state,您可以将响应数据带入反应上下文并让它知道它。

完整示例如下所示:

export default class AnalysisFila extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loaded: false
      opcion: {}
    };
  }

  componentDidMount() {
    const one = { codigo: this.props.codigo, rta: this.props.opcion };
    const rta = analysis.call(one, (err, res) => {
      this.setState({
        loaded: true,
        opcion: res
      }
    });
  }

  render() {
    const content = this.state.loaded ? this.state.opcion : 'Loading...';
    return (
     <Table.Row>
        <Table.Cell> {this.props.opcion} </Table.Cell>
        <Table.Cell> {content} </Table.Cell>
      </Table.Row>
    );
  } 
}

我还使用了 React 的 componentDidMount-Lifecycle-Method,因为它是触发 API 调用的推荐方式。您可以在 official lifecycle documentation

中阅读有关生命周期的更多信息

此组件的生命周期如下所示:

  1. 组件将被创建,构造函数将为 this.state
  2. 设置一个初始值
  3. render() 方法使用 this.state.loading === false 调用 - 因此内容将默认为字符串 'loading...'
  4. componentDidMount() 函数被调用并将触发您的 API-Call
  5. 您的回调被调用并执行 setState(),将响应数据放入 this.state
  6. 现在 React 知道状态已更改,它再次调用 render() 方法。但是这一次,this.state.loading === true 并且 this.state.opcion 有一些价值 - 因此内容将是您回复的价值。