Home > Software engineering >  refactoring Class component to function Component with react-redux
refactoring Class component to function Component with react-redux

Time:10-24

I am trying to refactor a Class component into a Function component in a react-redux app, but I am a bit stuck. When I try to convert this Component to a function Component, this line of code this.props.weather.map(this.renderWeather) no longer executes and it cannot read the list portion of code declared within the variables underneath the renderWeather() function

import React, {Component} from "react";
import { connect, useSelector } from "react-redux";
import Chart from "../containers/Chart";


class WeatherList extends Component {
  renderWeather(results) {
    const temp = results.list.map(weather => (weather.main.temp - 273.15) * 9/5   32);
    const pressure = results.list.map(weather => weather.main.pressure);
    const humidity = results.list.map(weather => weather.main.humidity);
    

    return (
      <tr key={results.city.id}>
        <td>{results.city.name}</td>
        <td>
          <Chart color='yellow' data={temp} units='F'/>
        </td>
        <td>
          <Chart color='green' data={pressure} units='hPa'/>
        </td>
        <td>
          <Chart color='blue' data={humidity} units='%'/>
        </td>
      </tr>
    )
  }

  render() {
    return (
      <table className="table table-hover">
        <thead>
          <tr>
            <th>City</th>
            <th>Temperature</th>
            <th>Pressure</th>
            <th>Humidity</th>
          </tr>
        </thead>
        <tbody>
          { this.props.weather.map(this.renderWeather) }
        </tbody>
      </table>
    )
  }
}

function mapStateToProps({ weather }) {
  return { weather }
}

export default connect(mapStateToProps)(WeatherList);

CodePudding user response:

So it depends where you want to get the weather data from.

  1. You could pass it as a prop
const WeatherList = (props) => {

    return (
      <table className="table table-hover">
        <thead>
          <tr>
            <th>City</th>
            <th>Temperature</th>
            <th>Pressure</th>
            <th>Humidity</th>
          </tr>
        </thead>
        <tbody>
          {props.weather.map(weatherItem => {
              // contents of renderWeather
              //
            }
          )}
        </tbody>
      </table>
    )

}
  1. You could grab it from the Redux Store via useSelector

const WeatherList = (props) => {
    const weather = useSelector(store => store.pathInStore.weather);
    //
    // Continue as above
    //
}

Note: You don't have to do the renderWeather inside the map as an anonymous function, it may be simpler to refactor it out to its own WeatherItem component or something.

CodePudding user response:

this.props only works in class components it does not work in functional components. you have hooks to manage state inside a FC.

here is Blog link to migrate from class base to function base in react.

CodePudding user response:

When refactoring Class components into Functional components you will lose "this", all your props will be no longer in this.props, you accept props as an argument in your functional component.

Use useSelector hook to get values from redux store.

Your final component will be something like this:

export const WeatherList(props){
  const weather = useSelector(weatherSelector);

  const renderWeather = (...) => {...} //Its better to move it to separate component

  return (
     ...
     {renderWeather(weather)}
     ...

  )
}

  • Related