0

I'm using redux with react. I have two separate js files that both get imported to an index.js Js file #1 has two TextFields; TextField #1 has a list of companies and TextField #2 has a list of contacts that's associated with a company selected from TextField #1. Js file #2 just has a copy of TextField #2 The issue I'm having here is that when I select a company from TextField #1 then TextField #2 in js file #1 gets updated but not TextField #2 in js file #2. State is stored in the redux store and not locally. This is js file #1:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as CompanyAction from '../../../../../actions/CompanyAction';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import TextField from '@material-ui/core/TextField';
import axios from 'axios';
class Component1 extends Component {
    constructor(props) {
        super(props);
        this.handleCompanyNameChange = this.handleCompanyNameChange.bind(this);
    }
    handleCompanyNameChange = e => {
        axios.get('/api/get/getCompany', {
            params: { id: e.target.value }
        }).then(({ data }) => {
            this.props.companyReducer.contacts = data.contacts;
            this.forceUpdate();
        });
    }
    componentDidMount = () => {
        axios.get('/api/get/companies').then(({ data }) => {
            data.sort((a, b) => (a.companyName > b.companyName) ? 1 : -1)
            this.props.companyReducer.companies = data;
            this.forceUpdate();
        });
    }
    handleGlobalChange = e => {
        e.preventDefault();
        this.props[e.target.name](e.target.value);
    };
    render() {
        const {
            handleCompanyNameChange,
            handleGlobalChange,
        } = this;
        return (
            <div>
                <TextField
                    select
                    label="Select Company"
                    value={this.props.companyReducer.companyId}
                    onChange={handleCompanyNameChange}
                    SelectProps={{}}>
                    <MenuItem value="">
                        <em>None</em>
                    </MenuItem>>
                        {this.props.companyReducer.companies.map((option, idx) => (
                        <MenuItem value={option.companyId}>
                            {option.companyName}
                        </MenuItem>
                    ))}
                </TextField>
                <TextField
                    select
                    label="Select Contact"
                    name="contactIdChange"
                    value={this.props.companyReducer.contactId}
                    onChange={handleGlobalChange}
                    SelectProps={{}}>
                    <MenuItem value="">
                        <em>None</em>
                    </MenuItem>>
                        {this.props.companyReducer.contacts.map((option, idx) => (
                        <MenuItem value={option.contactId}>
                            {option.firstName}
                        </MenuItem>
                    ))}
                </TextField>
            </div>
        )
    }
}
const mapStateToProps = (state, ownProps) => {
    return {
        companyReducer: state.companyReducer
    }
};
const mapDispatchToProps = (dispatch) => {
    return {
        companyNameChange: companyName => dispatch(CompanyAction.companyNameChange(companyName)),
    }
};
export default connect(mapStateToProps, mapDispatchToProps)(Component1 );

This is js file #2:

import React from 'react';
import { connect } from 'react-redux';
import * as CompanyAction from '../../../../../actions/CompanyAction';
import TextField from '@material-ui/core/TextField';
import Input from '@material-ui/core/Input';
import InputLabel from '@material-ui/core/InputLabel';
import MenuItem from '@material-ui/core/MenuItem';
class Component2 extends React.Component {
    constructor(props) {
        super(props);
    }
    handleGlobalChange = e => {
        e.preventDefault();
        this.props[e.target.name](e.target.value);
    };
    render() {
        const {
            handleGlobalChange,
        } = this;
        return (
            <div>
                <TextField
                    select
                    label="Select Contact"
                    name="contactIdChange"
                    value={this.props.companyReducer.contactId}
                    onChange={handleGlobalChange}
                    SelectProps={{}}>
                    <MenuItem value="">
                        <em>None</em>
                    </MenuItem>>
                        {this.props.companyReducer.contacts.map((option, idx) => (
                        <MenuItem value={option.contactId}>
                            {option.firstName}
                        </MenuItem>
                    ))}
                    </TextField>
            </div>
        )
    }
}
const mapStateToProps = (state, ownProps) => {
    return {
        companyReducer: state.companyReducer
    }
};
export default connect(mapStateToProps)(Component2 );

both these files get imported to one js file called index.js. Any help on this would be greatly appreciated.

Moe
  • 1
  • 2
  • I would like to add that when I click on the TextField #2 in js file #2 nothing shows, but when I select "none" from the dropdown then It populates with the correct info. – Moe Jan 09 '20 at 18:03
  • `this.props.companyReducer.contacts = data.contacts;` This is not the way to update the store. You need to dispatch an action to update the store via reducer. Because of above, you are doing `this.forceUpdate();`. This is most likely the cause of the issue. – Sunil Chaudhary Jan 09 '20 at 18:10
  • Yes, that worked! Thank you so much for pointing me in the right direction. – Moe Jan 09 '20 at 18:34
  • I'm getting in the console this message: Warning: Each child in a list should have a unique "key" prop." (sorry, I'm very new to redux & react so forgive my ignorance:-)) – Moe Jan 09 '20 at 18:35
  • Map function without keys is used at some places. Due to this, warning is coming. Please read more about this here: [Understanding unique keys for array children in React.js](https://stackoverflow.com/questions/28329382/understanding-unique-keys-for-array-children-in-react-js) – Sunil Chaudhary Jan 09 '20 at 19:01

0 Answers0