【问题标题】:Is It Possible To Trigger Contained Component's render from within the Container in React?是否可以从 React 的容器内触发包含组件的渲染?
【发布时间】:2017-04-08 00:09:15
【问题描述】:

所以我得到了App,它实现了componentDidMountrender

App 包含 2 个组件,一个是 AutoComplete 输入,另一个是 CardView

计划是一旦用户从AutoComplete 列表中选择了一个项目,将其显示在CardView

我想知道如何从AutoComplete 事件处理程序中触发CardView 的渲染(即设置它的状态)。

请参阅以下内容:

//愿意在这里触发 CardView 的渲染。

在下面的代码中。

import React, { Component } from 'react';
import injectTapEventPlugin from 'react-tap-event-plugin';

import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import AutoComplete from 'material-ui/AutoComplete';


// Needed for onTouchTap
// http://stackoverflow.com/a/34015469/988941
injectTapEventPlugin();

import './App.css';


class App extends Component {
  constructor () {
    super();
    this.state = {accounts: []}
    this.showAccount = this.showAccount.bind(this);
  }

  componentDidMount() {
    this.setState({ accounts: [
      {account_name: "foo", account_id: 1},
      {account_name: "bar", account_id: 2}
    ]})
  }

  showAccount (value) {
    // willing to trigger CardView's render right here.
  }

  render() {
    return (      
      <MuiThemeProvider>
        <div className="App">
        <center>
        <AutoComplete
          floatingLabelText="account name"
          filter={AutoComplete.caseInsensitiveFilter}
          dataSource={this.state.accounts.map((account) => account.account_name)}
          onUpdateInput={this.showAccount}
        /></center>
        <CardView />
        </div>
      </MuiThemeProvider>
    );
  }
}

export default App;

【问题讨论】:

  • 为什么不将道具传递给卡片?这样您就可以在您的节目帐户函数中设置状态并将该状态传递给卡片。
  • @usedToBeFat 在声明时,选择的值是已知的。如何在 showAccount 处理程序中引用 Card 的道具?
  • 在您的问题中,您声明一旦用户从自动完成列表中选择了一个项目,您就想显示该项目。如果我理解正确,那么您不需要卡片的渲染方法。你只需要它调用 setState 这将导致另一个渲染,这一次卡片将获得它将显示的道具。还是我错过了什么?
  • @usedToBeFat - 如果您可以使用我的代码来解释您的意思,那将是最好的。

标签: javascript reactjs


【解决方案1】:

根据我对您问题的理解,这是我的回答。

class CardView extends Component {
  constructor() {
    super()
  }

  render() {
    if (this.props.account) {
      return (
        <p>{this.props.account.account_name}</p>
      )
    }
    else {
      return (
        <p>no data</p>
      )
    }

  }
}
  class App extends Component {
  constructor () {
    super();
    this.state = {accounts: [], infoToDisplay: ''}
    this.showAccount = this.showAccount.bind(this);
  }

  componentDidMount() {
    this.setState({ accounts: [
      {account_name: "foo", account_id: 1},
      {account_name: "bar", account_id: 2}
    ]})
  }

  showAccount (value) {
    let infoToDisplay = this.state.infoToDisplay;
    infoToDisplay = value;
    this.setState({infoToDisplay}); 
    // this line will cause a rerender after the user has chosen something
    // from the autoComplete list
  }

  render() {
    return (      
      <MuiThemeProvider>
        <div className="App">
        <center>
        <AutoComplete
          floatingLabelText="account name"
          filter={AutoComplete.caseInsensitiveFilter}
          dataSource={this.state.accounts.map((account) => account.account_name)}
          onUpdateInput={this.showAccount}
        /></center>
        <CardView accounts={this.state.infoToDisplay} /> 
        </div>
      </MuiThemeProvider>
    );
  }
}

export default App;

我所做的是给应用程序组件状态以跟踪用户的选择。然后我将此状态作为道具传递给卡片组件。 当状态为满时,卡片将显示它,因此在 showAccount 函数中,我在 infoToDisplay 上调用 setState,这会导致另一个渲染,现在卡片的道具将充满最新信息并显示它。

希望这很清楚。

【讨论】:

  • 你为什么用let infoToDisplay = this.state.infoToDisplay; infoToDisplay = value; this.setState({infoToDisplay});而不是this.setState({infoToDisplay: value});
  • 不习惯。就像我有一个处于状态的对象被 onChange 填充。
  • 您能否编辑您的问题以显示您的卡代码?
  • 好的,只是为了确保问题不明显,我调用了道具 infoToDisplay,但您正在等待帐户。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-04
  • 2016-07-21
  • 2017-11-29
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多