简体   繁体   English

如何将prop传递给基于状态返回的组件?

[英]How to pass a prop to a component that is returned based on state?

I am attempting to return a component based on a parameter that was passed on a onClick handler this.showComponentToRender('features') . 我试图基于在onClick处理程序this.showComponentToRender('features')上传递的参数返回组件。 If features is clicked, it runs the showComponentToRender(name) and sets the state and in the render() , the {this.state.showComponent} shows the proper component. 如果单击功能,它将运行showComponentToRender(name)并设置状态,并在render(){this.state.showComponent}显示适当的组件。

However, a problem surfaces when I attempt to pass a prop resetFeatures={this.props.resetFeatures} within the 但是,当我尝试在内部传递prop resetFeatures={this.props.resetFeatures}时,问题resetFeatures={this.props.resetFeatures}

showFeatures() {
    return (<FeaturesList
             updateCad={this.props.updateCad}
             resetFeatures={this.props.resetFeatures}
           />);
  }

Clicking on the RESET A4 link, calls the resetCrossbow() which activates a function in the parent component. 单击RESET A4链接,调用resetCrossbow()激活父组件中的功能。 The parent component updates its state, and passes the state as a prop to its child. 父组件更新其状态,并将该状态作为道具传递给其子级。

For some reason, I can not get the resetFeatures prop to come into the <FeaturesList /> component if I return it within a function that gets set in state. 由于某些原因,如果我在设置为状态的函数中返回它,则无法使resetFeatures道具进入<FeaturesList />组件。 Why is this? 为什么是这样? I am looking for suggestions to fix. 我正在寻找修复建议。

If I do the traditional method of placing the <FeaturesList /> within the return of the render() , all is well. 如果我使用将<FeaturesList />放置在render()返回值内的传统方法,一切都很好。

Here's the component 这是组件

import React, { Component } from 'react';
import FeaturesList from  './FeaturesList';
import ColorsList from './ColorsList';
import './../assets/css/features-menu.css';

export default class FeaturesMenu extends Component {

  constructor(props) {
    super(props);

    this.state = {
      showComponent: this.showFeatures()
    };

    this.showFeatures = this.showFeatures.bind(this);
    this.showColors = this.showColors.bind(this);
  }

  showFeatures() {
    return (<FeaturesList
             updateCad={this.props.updateCad}
             resetFeatures={this.props.resetFeatures}
           />);
  }

  showColors() {
    this.props.resetCrossbow();
    return <ColorsList switchColor={this.props.switchColor} />
  }

  showComponentToRender(name) {
    if (name === 'features') {
      this.setState({
        showComponent: this.showFeatures()
      });
    } else {
      this.setState({
        showComponent: this.showColors()
      })
    }
  }

  render() {
    // console.log(`this.props.resetFeatures: ${this.props.resetFeatures}`);

    return (
      <div id="features-menu-wrapper">
        <nav id="features-menu">
          <li onClick={() => this.showComponentToRender('features')}>FEATURES</li>
          <li onClick={() => this.showComponentToRender('colors')}>COLORS</li>
          <li onClick={() => this.props.resetCrossbow()}>RESET A4</li>
        </nav>

        <div id="component-wrapper">
          {this.state.showComponent} // <- I am not able to pass resetFeatures prop if I do it this way. Why?

          {/* <FeaturesList
             updateCad={this.props.updateCad}
             resetFeatures={this.props.resetFeatures} <- I am able to pass resetFeatures prop as normal.
           />
          <ColorsList switchColor={this.props.switchColor} /> */}

        </div>
      </div>
    );
  }

}

You should not save the entire component in your state. 您不应该将整个组件保存在状态中。 Just set a string related to it and as the value changes, the FeaturesMenu will react and call the function to render the correct component. 只需设置一个与之相关的字符串,随着值的更改, FeaturesMenu将作出反应并调用该函数以呈现正确的组件。 Obviously, this code can be changed, but I think I've made my point. 显然,可以更改此代码,但我想我已经指出了。 =) =)

 const FeaturesList = props => (<div>Features List</div>); const ColorsList = props => (<div>Colors List</div>); class FeaturesMenu extends React.Component { constructor(props) { super(props); this.state = { currentComponent: 'Features' }; this.showFeatures = this.showFeatures.bind(this); this.showColors = this.showColors.bind(this); } showFeatures() { return (<FeaturesList updateCad={this.props.updateCad} resetFeatures={this.props.resetFeatures} />); } showColors() { this.props.resetCrossbow(); return <ColorsList switchColor={this.props.switchColor} /> } showComponentToRender(name) { this.setState({ currentComponent: name }) } render() { return ( <div id="features-menu-wrapper"> <nav id="features-menu"> <li onClick={() => this.showComponentToRender('Features')}>FEATURES</li> <li onClick={() => this.showComponentToRender('Colors')}>COLORS</li> <li onClick={() => this.props.resetCrossbow()}>RESET A4</li> </nav> <div id="component-wrapper"> {this[`show${this.state.currentComponent}`]()} </div> </div> ); } } // for testing purposes const props = { resetCrossbow: () => {}, switchColor: () => {}, updateCad: () => {}, resetFeatures: () => {} } ReactDOM.render(<FeaturesMenu {...props}/>, document.querySelector('main')) 
 <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> <main/> 

The easiest way to achieve results is pass additional properties to render specific components function and use spread to pass these props to the rendered component: 获得结果的最简单方法是传递其他属性以渲染特定组件的功能,并使用传播将这些道具传递给呈现的组件:

 const FeaturesList = ({additional = 'Empty'} = {}) => <div>Feature List with additional prop <b>{additional}</b></div> const ColorsList = ({additional = 'Empty'} = {}) => <div>Colors List with additional prop <b>{additional}</b></div> class FeaturesMenu extends React.Component { constructor(props) { super(props); this.state = { showComponent: this.showFeatures({additional: 'Initial features'}) }; this.showFeatures = this.showFeatures.bind(this); this.showColors = this.showColors.bind(this); } showFeatures(props) { return (<FeaturesList updateCad={this.props.updateCad} resetFeatures={this.props.resetFeatures} {...props} />); } showColors(props) { this.props.resetCrossbow(); return <ColorsList switchColor={this.props.switchColor} {...props} /> } showComponentToRender(name) { if (name === 'features') { this.setState({ showComponent: this.showFeatures({additional: 'features adds'}) }); } else { this.setState({ showComponent: this.showColors({additional: 'colors adds'}) }) } } render() { return ( <div id="features-menu-wrapper"> <nav id="features-menu"> <li onClick={() => this.showComponentToRender('features')}>FEATURES</li> <li onClick={() => this.showComponentToRender('colors')}>COLORS</li> <li onClick={() => this.props.resetCrossbow()}>RESET A4</li> </nav> <div id="component-wrapper"> {this.state.showComponent} </div> </div> ); } } const props = { resetCrossbow: () => null, switchColor: () => null, updateCad: () => null, resetFeatures: () => null } ReactDOM.render(<FeaturesMenu {...props}/>, document.querySelector('root')) 
 <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> <root/> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM