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.
- 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>
)
}
- 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)}
...
)
}