Reputation: 11030
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?
Upvotes: 4
Views: 5072
Reputation: 341
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);
Upvotes: 1
Reputation: 816312
When you .bind
parameters, those parameters become the first value(s) passed to the function. You should have noticed that when looking at the console.log
output.
I.e. when you do
var bar = foo.bind(this, x, y);
bar(z);
you get the values in this order:
function foo(x, y, z) {}
You have switch the order of parameters in your function:
renderContinent(checked, continent) {
// ...
}
However, you can just keep the code you have. You don't have to pass the value to renderContinents
.
In order to pass it to renderContinents
etc, either .bind
it or put the call inside another function:
continent.countries.map(renderCountries.bind(null, verified))
// or
continent.countries.map(country => renderCountries(country, verified))
Upvotes: 5