如何使用React js在onchange中将数据从一个组件传递到另一个组件

时间:2018-08-24 07:30:46

标签: javascript reactjs

我有两个组件1.过滤器和2.数据

我已将两个组件都注入了keep_default_na=False, na_values=['NaN']文件中

1.Main.js

main.js

2。过滤器组件

在过滤器中,组件具有两个下拉菜单1.颜色和2.class 基于下拉选择,需要将数据从过滤器组件传递到数据组件

render() {
        return (
            <div className={classes.Main}> 
                <Filter />
                <DataComponent />
            </div>
        );
    }

3。数据组件

import React from 'react'; 

const Filter = (props) => {
    return (
        <div>
          <ul>
            <li className={classes.displayInline} >
              <select name='color' onChange={this.handleChange} > 
                <option value='0'>Select</option>
                <option value='1'>red</option>
                <option value='2'>blue</option>
              </select>
            </li>
            <li className={classes.displayInline} >
              <select name='class' >
                <option value='0'>Select Class</option>
                <option value='1'>first</option>
                <option value='2'>Second</option>
                <option value='3'>Third</option>
                <option value='4'>Fourth</option>
              </select>
            </li>
          </ul>
        </div>
    );
}

export default Filter;

需要将下拉值从过滤器组件转换为数据组件。

我对reactjs框架有新的了解。

3 个答案:

答案 0 :(得分:4)

  

在过滤器组件中

handleChange = (event) => {
    if(typeof this.props.selectedValueHandler !== 'undefined'){
        this.props.selectedValueHandler(event.target.value);
    }
}
  

在主要组件中

在主文件中,您需要将函数selectedValueHandler传递为 过滤器组件的道具,它将用作回调过滤器组件 从Filter组件内部进行选择。

然后可以将所选值传递到Data Componennt

constructor() {
    this.state = {
        selectedValue: null
    }
}

selectedValueHandler = (selectedValue) => {
    this.setState({
        selectedValue
    })
}

render() {
        const { selectedValue } = this.state;
        return (
            <div className={classes.Main}> 
                <Filter selectedValueHandler={this.selectedValueHandler}/>
                <DataComponent selectedValue={selectedValue} />
            </div>
        );
    }
  

在您的数据组件中

您可以使用

直接访问“数据组件”中的选定值
class DataComponent extends Component {
    render() {
        const { selectedValue } = this.props;
        ...
    }
}

,或者如果要使其成为数据组件状态的一部分。

class DataComponent extends Component {

    constructor(props) {
        super(props);
        this.state = { 
            items: [],
            content: [],
            selectedValue: this.props.selectedValue
        }
    } 

    componentwillreceiveprops(nextProps) {
        if(this.state.selectedValue !== nextProps.selectedValue) {
            this.setState({
                selectedValue: nextProps.selectedValue
            })
        }

    }

    render() {
        const { selectedValue } = this.state;
        ...
    }
}

取决于您的用例。

答案 1 :(得分:3)

据我所知,有两种方法可以解决此问题:

  1. 使用Redux来控制应用程序的通用状态。请在Redux网站(https://redux.js.org/basics/exampletodolist)中查看示例

  2. 使用父母的状态

在您的Main.js 中,将更改包含在其子 Filter

中的状态
constructor(props) {
    super(props);
    this.state = { 
        value: null, //used to contains your dropdown value
    }
    this.getDropdownData = this.getDropdownData.bind(this);
} 

以及用于从过滤器获取值的功能

getDropdownData(value){
    this.setState({
        value : myvalue
    });
}

然后将getDropdownData()函数传递给 Filter 数据,并将value处于状态传递给 Data Component

render() {
        return (
            <div className={classes.Main}> 
                <Filter getDropdownData = {this.getDropdownData}/>
                <DataComponent dropdownValue = {this.state.value}/>
            </div>
        );
    }

在Filter.js中

使用this.handleChangethis.props.getDropdownData(input_dropdown_value)中调用传递的函数

不要忘记将this.handleChange绑定到constructor()

this.handleChange = this.handleChange.bind(this)

最后

通过调用this.props.dropdownValue

使用 DataComponent 中的下拉值

希望它可以为您提供帮助

答案 2 :(得分:1)

我的第一个直觉是说您应该将两个组件简单地组合为一个。

由于某种原因,组件具有承载状态的能力。使用功能组件然后将其状态拆分为一个单独的组件没有什么意义。

content.push函数中包含render对于React来说也有些奇怪。您的render函数应全权负责渲染,没有其他责任。如果您想在render函数中做某事,请创建一个处理程序。

这里是构建过滤器类的方式,请记住,这段代码是未经测试而编写的,因此可能需要进行一些调整,但是总的结构就在那里。

import React from 'react'

export default class Filter extends React.Component {
  constructor (props) {
    super(props)

    this.state = {
      items: [],
      content: [],
      isLoaded: false,
      error: null,
      selectedColorFilter: null,
      selectedClassFilter: null
    }

    //There's probably a better way to refactor this so it's just one handler, but I'm just using two for illustrative purposes here.
    this.handleColorFilterChange = this.handleColorFilterChange.bind(this)
    this.handleClassFilterChange = this.handleClassFilterChange.bind(this)
  }

  componentDidMount () {
    fetch('url')
      .then((res) => {
        return res.json()
      })
      .then((data) => {
        this.setState({
          isLoaded: true,
          items: data
        })
      })
      .catch((error) => {
        this.setState({
          isLoaded: false,
          error: error
        })
      })
  }

  handleColorFilterChange (event) {
    //this may not be right, but I think it'll pick up the right value, may have to change it
    this.state.selectedColorFilter = event.target.value
  }

  handleClassFilterChange (event) {
    //again, might not be right, but I think it'll grab the value
    this.state.selectedClassFilter = event.target.value
  }

  renderColorFilter () {
    <li className={classes.displayInline} >
      <select name='color' onChange={this.handleColorFilterChange} > 
        <option value='0'>Select</option>
        <option value='1'>red</option>
        <option value='2'>blue</option>
      </select>
    </li>
  }

  renderClassFilter () {
    <li className={classes.displayInline} >
      <select name='class' onChange={this.handleClassFilterChange} >
        <option value='0'>Select Class</option>
        <option value='1'>first</option>
        <option value='2'>Second</option>
        <option value='3'>Third</option>
        <option value='4'>Fourth</option>
      </select>
    </li>
  }

  render () {
    return (
      <div>
        <ul>
          {this.renderColorFilter()}
          {this.renderClassFilter()}
        </ul>
      </div>
    )
  }
}

希望这很有道理。