update component from another component in react

Viewed 2218

Sorry about the question, I am new at react.

I have one component "QuickLaunch" containing 2: a react-select based component "MySelect" and a custom datatable component (Datatable).

The render function in Quicklaunch looks like this:

render() {
    return (...
        <MySelect item="lists" searchField="name" condition="list_type_id=1" multi={true} name="select-list"/>
        ...
        <Datatable options={{...}}>
...)}

What I need is to add an item to the react-select component (like I would if I selected an item in that react-select component) but when I click on a row in the table. I know how to do this with custom components but I can't do it precisely with react-select as I don't want to modify the source of the package. Is this possible ? Here is MySelect source:

import React from 'react'
//import PropTypes from 'prop-types';
import Msg from '../i18n/Msg'
import PropTypes from 'prop-types';

//https://jedwatson.github.io/react-select/
import Select from 'react-select';


import mtpSettings from '../../config/mtp4.json'
import { setRequestHeaders, formsForOptions } from '../../lib/mtp.js'




export default class MySelect extends React.Component {

    constructor(props) {
        super(props)
        this.props = props
        this.state = {value: ''};
    }

    // componentDidMount = () => {
    //  this.setState({
    //      value: '',
    //  })
    // }

    getOptions = (input) => {
        if (!input) {
            return Promise.resolve({ options: [] });
        }
        let fetchData = {
            "headers": setRequestHeaders(),
            "method": "GET"
        }

      //let url = mtpSettings.mtp4Config.apiBaseUrl + 'lists' + "?limit=50&" + "name" + "=%" + input + "%" 
      let url = mtpSettings.mtp4Config.apiBaseUrl + this.props.item + "?limit=50&" + 
      this.props.searchField + "=%" + input + "%&" +  this.props.condition
      return fetch(url, fetchData)
        .then((response) => {
            // console.log(response.json())
            return response.json()
        })
        .then((items) => {
            let options = formsForOptions(items, "id_list", "name")
            return { options: options }
        })
    }

    onChange = (value) => {
        this.setState({
            value: value,
        })
    }

    render() {
        //const AsyncComponent = this.state.creatable ? Select.AsyncCreatable : Select.Async;
        /*<AsyncComponent multi={this.state.multi} value={this.state.value} 
        onChange={this.onChange} onValueClick={this.gotoUser} valueKey="id" labelKey="login" 
        loadOptions={this.getUsers} backspaceRemoves={this.state.backspaceRemoves} />
        */  

        return (
            <div>
            <Select.Async
              name={this.props.name} 
              autoload={true} 
              value={this.state.value} 
              loadOptions={this.getOptions}
              onChange={this.onChange} 
              backspaceRemoves={true}
              multi={this.props.multi}
              id={this.props.id}
            />
            </div>
        )
    }
}

Thanks a lot !

2 Answers

You Can add list in QuickLaunch Component and put into state then after on click of row get that row data and accordingly update the list.

I resolved it but I don't know if that's the correct way:

  • in QuickLaunch, I added a ref to my select like this: render() { return ( ... <MySelect ref="selectList" ...
  • Then in the MySelect component, I added a method (using an arrow function to get the correct "this"), for example addOption, like this: addOption = (option) => { this.setState({ value: option }) }

  • And back in my main component "QuickLaunch" I just had to add an event (for instance the onDrop of a dropzone) that would execute the method onDrop(files) { ... var selectList = this.refs.selectList selectList.addOption({label: 'aLabel', value: 'aValue'}) ... }

Let me know if that helped anyone.

Related