[英]Redux: Call to action-creator returns 'Cannot read property 'props' of undefined'
I'm able to fetch the weather by a given city but can't figure how to delete it afterwards. 我可以按给定的城市获取天气,但无法弄清楚以后如何删除。 Being still new to Redux I'm trying to figure which pieces am I missing on this puzzle.
还是Redux的新手,我想弄清楚这个难题中我缺少哪些部分。
I'm leaving the FETCH_WEATHER code in just for context proposes. 我仅将FETCH_WEATHER代码留给上下文建议。 My issues is with the DELETE_CITY implementation.
我的问题是关于DELETE_CITY实现。
Steps: 脚步:
Add a button in each row that calls an action creator. 在每行中添加一个调用动作创建者的按钮。
Action creator takes the name of the 'city' and return an action of type 'DELETE_CITY'. 动作创建者使用“城市”的名称,并返回类型为“ DELETE_CITY”的动作。
Reducer, watches for that type and iterates through the array of cities and deletes the object with the given city name. Reducer会监视该类型,并迭代城市数组,并删除具有给定城市名称的对象。
action creator 动作创造者
import axios from 'axios';
const API_KEY = '1111111111111111111111';
const ROOT_URL = `http://api.openweathermap.org/data/2.5/forecast?appid=${API_KEY}`;
export const FETCH_WEATHER = 'FETCH_WEATHER';
export const DELETE_CITY = 'DELETE_CITY';
//fetch cities
export function fetchWeather(city){
const url = `${ROOT_URL}&q=${city},&units=imperial`;
const request = axios.get(url);
console.log('Request:', request);
return {
type: FETCH_WEATHER,
payload: request
}
}
//Delete Cities
export function deleteCity(city) {
return {
type: DELETE_CITY,
payload: city
}
}
Reducer: index.js 减速器:index.js
import { combineReducers } from 'redux';
import WeatherReducer from './reducer_weather';
const rootReducer = combineReducers({
weather: WeatherReducer
});
export default rootReducer;
weather_reducer.js weather_reducer.js
Is the case for DELETE_CITY implemented accurately? DELETE_CITY的情况是否得到正确实施?
import { FETCH_WEATHER } from '../actions/index';
import { DELETE_CITY } from '../actions/index';
export default function (state = [], action) {
console.log('Action received', action);
//only fetch weather data type
switch (action.type) {
case FETCH_WEATHER:
//concat to prevent state mutation
return state.concat([action.payload.data]);
case DELETE_CITY:
return state
.slice(0, action.payload.data)
.concat([action.payload.data].slice([action.payload.data] + 1));
}
return state;
}
Ps:Are mapStateToProps and mapDispatchToProps correct? ps:mapStateToProps和mapDispatchToProps是否正确?
weather_container.js weather_container.js
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Chart from '../components/chart';
import GoogleMap from '../components/google_map';
import { bindActionCreators } from 'redux';
import { deleteCity } from '../actions/index';
class WeatherList extends Component {
renderWeather(cityData) {
const name = cityData.city.name;
return (
<tr key={name}>
<td><button onClick={() => this.props.deleteCity(cityData)} className="btn btn-danger">x</button></td>
</tr>
)
}
render() {
return (
<table>
<thead>
<tr>
<th>City</th>
</tr>
</thead>
<tbody>
{this.props.weather.map(this.renderWeather)}
</tbody>
</table>
)
}
}
function mapStateToProps(state) {
return {
weather: state.weather
}
}
function mapDispatchToProps(dispatch, weather) {
return bindActionCreators({deleteCity},{weather}, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps)(WeatherList);
I need to bind the action creator to the onClick event. 我需要将动作创建者绑定到onClick事件。 I tried both methods: fat arrow functions and/or 'binding the method inside of a constructor()'.
我尝试了两种方法:胖箭头函数和/或“将方法绑定到builder()内部”。
They both return with props undefined. 他们都带着未定义的道具返回。
You need to bind renderWeather
function. 您需要绑定
renderWeather
函数。
class WeatherList extends Component {
constructor(){
super();
this.renderWeather = this.renderWeather.bind(this);
}
...
}
The error message you're getting cannot read property props of undefined
means that in this.props
this
is undefined. 您收到的错误消息
cannot read property props of undefined
this.props
this
意味着在this.props
this
是未定义的。
It's a common gotcha in react, mainly because this is falling out of context. 这是反应中的常见陷阱,主要是因为这不在上下文范围内。
What you need to do is bind the renderWeather function to WeatherList in the constructor 您需要做的是将renderWeather函数绑定到构造函数中的WeatherList
constructor() {
this.renderWeather = this.renderWeather.bind(this)
}
Another alternative is to use arrow functions 另一种选择是使用箭头功能
class {
renderWeather = (weatherData) => {
...
}
...
}
You might also consider this implementation in you reducer when deleting a city. 删除城市时,您可能还会在减速器中考虑此实现。
[...state].filter((weather) => {
return weather.id != action.payload.data.id
})
.filter()
returns a new array of items that meet the given condition .filter()
返回满足给定条件的新项目数组
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.