How to pass data from one component to another component in onchange using React js

前端 未结 3 426
攒了一身酷
攒了一身酷 2021-01-28 22:30

I have two component 1. Filter and 2.Data

I have injected both components in main.js file

1.Main.js

render() {
        return (
            


        
相关标签:
3条回答
  • 2021-01-28 23:08

    My first instinct is to say that you should simply combine the two components into one.

    Components have the ability to carry state for a reason. There's not much point using a functional component and then splitting it's state into a separate component.

    Having content.push in your render function also is a bit weird to do for React. Your render function should be solely responsible for rendering, nothing else. If you want to do something in your render function, make a handler.

    Here's how I'd build your filter class, bear in mind this code is written without being tested so it may require some tweaks, but the general structure is all there.

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

    Hope this makes sense.

    0 讨论(0)
  • 2021-01-28 23:09

    According to my knowledge, there are 2 way for solving this problem:

    1. Using Redux for controlling the common state of your application. Please see an example in Redux website (https://redux.js.org/basics/exampletodolist)

    2. Using parent's state

    In your Main.js init the state for containing the change in its child Filter

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

    and the function for getting the value from Filter

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

    then pass the getDropdownData() function to getting data to Filter and the value in state to Data Component

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

    In Filter.js

    Call the passed function in this.handleChange by using this.props.getDropdownData(input_dropdown_value)

    Do not forget to bind this.handleChange in the constructor()

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

    Finally

    Using the drop-down value in DataComponent by calling this.props.dropdownValue

    Hope it can help you

    0 讨论(0)
  • 2021-01-28 23:16

    In Filter Component

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

    In Main Component

    In you main file you need to pass a function selectedValueHandler as a prop to the filtercomponent, which will be used as a callback filtercomponent from inside the Filter component on selection.

    The selected value then can be passed to 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>
            );
        }
    

    In your Data Component

    You can directly access the selected value in Data Component using

    class DataComponent extends Component {
        render() {
            const { selectedValue } = this.props;
            ...
        }
    }
    

    or if you want to make it part of Data Component State.

    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;
            ...
        }
    }
    

    Depends on your use case.

    0 讨论(0)
提交回复
热议问题