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

IT技术 javascript reactjs
2021-05-18 04:16:25

我有两个组件 1. Filter 和 2.Data

我已经在main.js文件中注入了两个组件

1.Main.js

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

2.过滤组件

在过滤器中,组件有两个下拉列表 1.color 和 2.class 基于下拉选择需要将数据从过滤器组件传递到数据组件

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;

3.数据组件

import React, { Component } from 'react'; 
class DataComponent extends Component {
    constructor(props) {
        super(props);
        this.state = { 
            items: [],
            content: [],
        }

    } 
    componentDidMount() {
        fetch("url")

            .then(res => res.json())
            .then(
                (result) => {
                    this.setState({
                        isLoaded: true,
                        items: result
                    });
                },
                (error) => {
                    this.setState({
                        isLoaded: true,
                        error
                    });
                }
            )

    } 
    render() {

            /**** data getting from api is pushed to content ****/

            content.push(items);
        });
        return ( 
         /**** render part ***/

        )
    } 
}
export default DataComponent;

需要从过滤器组件到数据组件获取下拉值。

我对 reactjs 框架有新的认识。

3个回答

在过滤器组件中

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

在主要组件中

在您的主文件中,您需要将一个函数selectedValueHandler作为props传递给过滤器组件,它将在选择时用作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. 使用 Redux 来控制应用程序的公共状态。请参阅 Redux 网站(https://redux.js.org/basics/exampletodolist)中的示例

  2. 使用父状态

在您的 Main.js init 中,在其子过滤器中包含更改的状态

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

以及从 Filter 获取值的函数

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

然后传递getDropdownData()函数来获取数据到过滤器value状态到数据组件

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

在 Filter.js 中

this.handleChange通过使用调用传入的函数this.props.getDropdownData(input_dropdown_value)

不要忘记绑定this.handleChangeconstructor()

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

最后

通过调用DataComponent 中使用下拉值this.props.dropdownValue

希望能帮到你

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

组件具有携带状态的能力是有原因的。使用功能组件然后将其状态拆分为单独的组件并没有多大意义。

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>
    )
  }
}

希望这是有道理的。