K.Rice K.Rice - 4 months ago 18
Javascript Question

Calling forceUpdate inside jsx

I'm not good with

this
notation, so I have some troubles when try to call method forceUpdate() inside my jsx.

class WeatherList extends Component {
renderWeather(cityData){


//some code


return(
<tr key={id}>
<td>
<div>{name}</div>
<h4 onClick={ () => {
var toChange = JSON.parse(localStorage.nameForData);
for(var i in toChange){
if(toChange[i].city.id = id){
toChange.splice(i,1);
}
}
localStorage.nameForData = JSON.stringify(toChange);
forceUpdate();

}} >Delete</h4>
</td>
<td><Chart data={temps} color='orange' units='K' /></td>
<td><Chart data={pressures} color='blue' units='hPa' /></td>
<td><Chart data={humidities} color='green' units='%' /></td>
</tr>
);
}`


I tried to bind
forceUpdate
to
this
in constructor, but I'm having error message
Cannot read property 'forceUpdate' of undefined
again and again. Please, help me.

Full code

class WeatherList extends Component {


renderWeather(cityData){
const name = cityData.city.name;
const temps = cityData.list.map(weather => weather.main.temp);
const pressures = cityData.list.map(weather=>weather.main.pressure);
const humidities = cityData.list.map(weather=>weather.main.humidity);
const id = cityData.city.id;



return(
<tr key={id}>
<td>
<div>{name}</div>
<h4 onClick={ () => {
var toChange = JSON.parse(localStorage.nameForData);
for(var i in toChange){
if(toChange[i].city.id = id){
toChange.splice(i,1);
}
}
localStorage.nameForData = JSON.stringify(toChange);
forceUpdate();

}} >Delete</h4>
</td>
<td><Chart data={temps} color='orange' units='K' /></td>
<td><Chart data={pressures} color='blue' units='hPa' /></td>
<td><Chart data={humidities} color='green' units='%' /></td>
</tr>
);
}


render(){

var arr = JSON.parse(localStorage.getItem('nameForData'));

arr = arr.concat(this.props.weather);

localStorage.setItem('nameForData', JSON.stringify(arr));

//localStorage.setItem('nameForData', JSON.stringify(this.props.weather));
console.log(arr);

return(
<table className="table">
<thead>
<tr>
<th>City</th>
<th>Temperature (K)</th>
<th>Pressure (hPa)</th>
<th>Humidity (%)</th>
</tr>
</thead>
<tbody>
{arr.map(this.renderWeather)}
</tbody>
</table>
);
}


}`

Answer

You shouldn't bind forceUpdate function. Use it by calling this.forceUpdate().

Correct code:

// `renderWeather` function:

<h4 onClick={ () => {
    var toChange = JSON.parse(localStorage.nameForData);
    for(var i in toChange){
        if(toChange[i].city.id = id){
            toChange.splice(i,1);
        }
    }
    localStorage.nameForData = JSON.stringify(toChange);
    this.forceUpdate();

}} >Delete</h4>

As you are passing this.renderWeather function to map, it this context would be undefined, to set correct this context, you should pass it as second argument to map function:

// `render` function:

<tbody>
  {arr.map(this.renderWeather, this)}
</tbody>