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 getting error message Cannot read property 'forceUpdate' of undefined again and again.

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>
    );
}
}
1

1 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>
4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Maya Lin-Takahashi

Maya Lin-Takahashi

Consumer Tech & Gadget Reviewer

Maya is a hardware enthusiast who tests and reviews smart home devices, smartphones, wearables, and audio gear. She focuses on practical consumer value and build quality.

Share this article
Twitter Facebook Pinterest