I am handling a 404 error
by changing the redux
state in a React
app, so if the there's an error
, I update the state.error
to 404
and I render
a component depending on that state. This the display()
function inside my React
container.
display() {
const { weather: { weathers } } = this.props;
const error = this.props.weather.error;
console.log('props ', this.props);
console.log('props weather', this.props.weather, 'w err', this.props.weather.error);
console.log('error ', error);
if (error !== 0) {
return <ErrorMssg error={error} />;
}
if (weathers.length === 1) {
return <div>hai</div>;
}
return <Chart data={weathers}/>;
}
I console log this.props and the redux state in the mapStateToProps
function, and I can see the state updates successfully if there's a 404 catch. I can even see that if I console log this.props in the chrome console, and I expand it I can see the error value as I would expect (although the value before the object expansion is not the one that shows after the expansion, see image), but if I console log this.props.weather.error it shows me an unexpected value.
Here is the chrome console log:
here's the code of the reducer
export default (state: I.StoreState = defaultState, action: T.AWeather): I.StoreState => {
const { type, payload } = action;
switch (type) {
case FETCH_WEATHER:
const _data = 'data';
const data = payload[_data];
const { name, country } = data.city;
const weathers: I.Weather[] = [];
for (let i = 0; i < data.list.length; i = i + 3) {
let item = data.list[i];
let { dt_txt } = item;
let schedule = dt_txt ? dt_txt.split(' ') : '';
let { humidity, pressure, temp } = item.main;
weathers.push({
date: schedule[0],
time: schedule[1],
humidity,
pressure,
temp
});
}
return {
city: { name, country },
weathers,
error: 0
};
case ERROR_NOT_FOUND:
defaultState.error = 404;
return defaultState;
default:
return state;
}
};
And here;s the code of the action
export const fetchWeather = (searchValues: I.Search): T.AWeather | object => {
const { city, country } = searchValues;
const url: string = `${ROOT_URL}&q=${city},${country}`;
const response: T.AWeather | object = axios.get(url)
.then( res => ({
type: FETCH_WEATHER,
payload: res
}))
.catch( error => ({
type: ERROR_NOT_FOUND,
payload: error.response.status
}));
return response;
};
EDIT
Note: I am using redux-form
that updates the redux state
when I click a form input, so after I submit and the error
still shows as 0, but when I click the form it does logs and renders as expected.
Also, when I expand the console log in Chrome it shows it updated the state
(even if it's after the log, showing Chrome's object's revaluation like Dan O explained).. shouldn't the container re-render when the state
is changed??
答案 0 :(得分:0)
when you console.log
an object to the Chrome console, you see a few fields in that object and also a triangle icon which you can click to expand the object and view its complete contents. When you click that icon, Chrome re-evaluates the contents of the object. Those contents might be different now than what they were when you logged to console, e.g. if a state object is mutated.
See here for more information: Getting chrome console to show object values as they were.
So that is why you have a mismatch between this.state
and console.log
.
But also, according to your image you are rendering your component before your axios request returns. error
is set to 0 (maybe in defaultState
?) so console.log gives you 0, then axios returns 404 some time in the future. You'll need to make another state update or trigger a re-render some other way if you want to see those changes rendered in your component.
答案 1 :(得分:0)
好的,我发现了发生了什么..问题是我以前做过的减速机的返回:
case ERROR_NOT_FOUND:
defaultState.error = 404;
return defaultState;
,其中
const defaultState: I.StoreState = {
city: {name: '', country: ''},
weather: [{
date: '',
time: 'string',
humidity: 0,
pressure: 0,
temp: 0
}],
error: 0
};
我认为既然我没有改变状态,只是返回一个新对象它会起作用,但事实并非如此,你必须像这样返回:
case ERROR_NOT_FOUND:
return {
city: defaultState.city,
weather: defaultState.weather,
error: 404
};