lost9123193 lost9123193 - 3 months ago 7
React JSX Question

Passing functions and variables as arguments to map() in Javascript/React

I want to pass a prop called

verified
through each map function and I am having difficulty setting it up.

UPDATE:

Passing
verified
to renderContinents works, but when add a parameter to renderCountry like this:

{continent.countries.map(renderCountry(null, verified))}


My output is blank. Shouldn't this work though?

Updated code:

const renderCities = cities => {
return (
<div>
<label>
<input
onChange={onChange}
type="checkbox"/>
{cities.name}
</label>
</div>
);
};

const renderCountries = ({country, verified}) => {
console.log("came to country");
return (
<div className="city-location">
<label>
<input
onChange={onChange}
type="checkbox"/>
{country.name}
</label>
{country.cities.map(renderCities)}
</div>
);
};



function onChange(e) {
console.log('checkbox verified:', (e.target.verified));
}


class AreasComponent extends Component {
constructor(props) {
super(props);
this.state = {
};
this.renderContinents = this.renderContinents.bind(this);
}

componentWillMount() {
this.props.fetchAllAreas();
}

renderContinents(verified, continent) {
console.log("came to continent");
return(
<div className="continent-location">
<label>
<input
onChange={onChange}
type="checkbox"/>
{continent.name}
</label>

{continent.countries.map(renderCountries(null, verified))}

</div>
)
}


render() {
if (!this.props.verified || !this.props.areas) {
return <div>Loading Areas...</div>
}
return(
<div>
{this.props.areas.map(this.renderContinents.bind(this, this.props.verified))}
</div>
);
}
}

function mapDispatchToProps(dispatch){
return bindActionCreators({ fetchAllAreas, checkArea}, dispatch);
}


function mapStateToProps(state) {
return { areas: state.areas.all,
verified:state.areas.verified
};
}


export default connect(mapStateToProps, mapDispatchToProps)(AreasComponent);


My other problem is the
onChange(e)
function. It's global so it works when I click any checkbox, but I want to make it so that when onChange is clicked, it can take in a parameter and dispatch the action
checkArea
, which, to me means it has to be bound and should also be fed as a parameter. I tried this:

{this.props.areas.map(this.renderContinents.bind(this, this.props.verified, this.props.checkArea))}


but it returns a blank result. Is it possible to send a function into a map () parameter and is there a way to get renderCountry/renderCity to work with parameters?

Answer

In fact, the simplest way for renderCountry/renderCity to call onChange() with checkArea action is to put them inside AreasComponent (i.e. as member functions). So they can access both onChange and checkArea.

class AreasComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {};
        this.onChange = this.onChange.bind(this);
    }

    componentWillMount() {
        this.props.fetchAllAreas();
    }

    onChange(e, type) {
        console.log('checkbox verified:', this.props.verified);
        // call checkArea() here with your parameters
        this.props.checkArea(type);
    }

    renderCities(cities) {
        return (
            <div>
                <label>
                    <input
                        onChange={e => this.onChange(e, 'city')}
                        type="checkbox"/>
                    {cities.name}
                </label>
            </div>
        );
    };

    renderCountries(country) {
        console.log("came to country");
        return (
            <div className="city-location">
                <label>
                    <input
                        onChange={e => this.onChange(e, 'country')}
                        type="checkbox"/>
                    {country.name}
                </label>
                {
                    country.cities.map(this.renderCities)
                }
            </div>
        );
    };

    renderContinents(continent) {
        console.log("came to continent");
        return(
            <div className="continent-location">
                <label>
                    <input
                        onChange={e => this.onChange(e, 'continent')}
                        type="checkbox"/>
                    {continent.name}
                </label>
                {
                    continent.countries.map(this.renderCountries)
                }
            </div>
        )
    }

    render() {
        if (!this.props.verified || !this.props.areas) {
            return <div>Loading Areas...</div>
        }
        return(
            <div>
                {
                    this.props.areas.map(this.renderContinents)
                }
            </div>
        );
    }
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({ fetchAllAreas, checkArea}, dispatch);
}


function mapStateToProps(state) {
    return {
        areas: state.areas.all,
        verified: state.areas.verified
    };
}


export default connect(mapStateToProps, mapDispatchToProps)(AreasComponent);
Comments