Thử React + Redux, và có thể đang làm điều gì đó rõ ràng là ngu ngốc, vì một thành phần kích hoạt một hành động tìm nạp dữ liệu qua mạng không được cập nhật (kết xuất lại) khi dữ liệu được tìm nạp.React + Redux: Thành phần không cập nhật
Dưới đây là các bit có liên quan của mã của tôi:
Các index.js cấp cao nhất phục vụ như là một điểm khởi đầu cho các ứng dụng:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, browserHistory } from 'react-router';
import reduxPromise from 'redux-promise';
import createLogger from 'redux-logger';
const logger = createLogger();
import routes from './routes';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware(reduxPromise, logger)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<Router history={browserHistory} routes={routes} />
</Provider>
, document.querySelector('.container'));
chứa cấp cao nhất App:
import React, {Component} from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as Actions from '../actions';
import Header from '../components/header';
import Showcase from '../components/showcase';
function mapStateToProps(state) {
return {
resources: state.resources
}
}
function mapDispatchToProps(dispatch) {
return {
fetchResources:() => {
dispatch(Actions.fetchResources());
}
}
}
class App extends Component {
render() {
console.log('props in App', this.props);
return (
<div>
<Header/>
<Showcase
fetchResources={this.props.fetchResources}
resources={this.props.resources}
/>
</div>
);
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(App)
Thành phần kích hoạt tác vụ gửi yêu cầu dữ liệu khi nó sắp được gắn kết và được cho là hiển thị dữ liệu được tìm nạp:
import React, {Component} from 'react';
import {connect} from 'react-redux';
class Showcase extends Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.fetchResources();
}
render() {
console.log('resources', this.props);
return (
<div>
This is showcase
</div>
);
}
}
export default connect(state => ({resources: state.resources}))(Showcase)
Action Creator:
import * as types from '../constants/ActionTypes';
import axios from 'axios';
export function fetchResources() {
return {
type: types.FETCH_FIRST,
payload: axios.get('/sampledata/1.json')
}
}
Giảm cho lấy hành động:
import * as types from '../constants/ActionTypes';
export default function resourcesReducer (state={}, action) {
switch (action.type) {
case types.FETCH_FIRST:
console.log('about to return', Object.assign (state, {resources: action.payload.data }))
return Object.assign (state, {resources: action.payload.data });
default:
return state
}
};
và cuối cùng là giảm root:
import { combineReducers } from 'redux';
import navigationReducer from './navigation-reducer';
import resourcesReducer from './resources-reducer';
const rootReducer = combineReducers({
navigationReducer,
resourcesReducer
});
export default rootReducer;
Vì vậy, đây là những gì tôi đang quan sát. Hành động yêu cầu dữ liệu được kích hoạt thành công, yêu cầu được gửi đi, trình giảm sẽ nhận được yêu cầu đó khi lời hứa được giải quyết và cập nhật trạng thái với dữ liệu được tìm nạp. Tại thời điểm này, tôi mong đợi thành phần App
cấp cao nhất và thành phần Showcase
để phát hiện rằng cửa hàng đã cập nhật và để hiển thị lại, nhưng tôi không thấy nó trong bảng điều khiển.
Ngoài ra, tôi bối rối bởi redux-logger
's giao diện điều khiển đầu ra:
Cụ thể, tôi ngạc nhiên khi thấy rằng các state
chứa gia giảm từ rootReducer - Tôi không biết nếu nó là đúng (một ví dụ trên Redux logger Github page hiển thị trạng thái không có bộ giảm tốc). Nó cũng có vẻ ngạc nhiên khi prev state
được báo cáo bởi redux-logger
chứa cùng một đối tượng resourcesReducer
là next state
, mặc dù theo trực giác tôi mong đợi prev state
ít nhiều trống.
Bạn có thể vui lòng chỉ ra những gì tôi đang làm sai và cách nhận các thành phần React phản hồi lại các thay đổi của state
?
============================================== ====
CẬP NHẬT:
1) Thay đổi mapStateToProps
chức năng trong thành phần App
để nó một cách chính xác bản đồ để giảm trạng thái:
function mapStateToProps(state) {
return {
resources: state.resourcesReducer
}
}
2) Tuy nhiên vượt qua resources
xuống thành phần `Showcase:
render() {
console.log('props in App', this.props);
return (
<div>
<Header navigateActions={this.props.navigateActions}/>
React simple starter
<Showcase
fetchResources={this.props.fetchResources}
resources={this.props.resources}
/>
</div>
);
3) Đang cố gắng để hiển thị resources
trên màn hình bằng stringifying nó để xem những gì thực sự bên trong đối tượng này:
render() {
console.log('resources', this.props);
return (
<div>
This is showcase {JSON.stringify(this.props.resources)}
</div>
);
}
Xem này trên màn hình: This is showcase {}
. Các thành phần dường như không tái render.
Đây là ảnh chụp màn hình của bảng điều khiển cho biết rằng đạo cụ của Ứng dụng đã được cập nhật với các giá trị từ số next state
. Tuy nhiên, điều đó không gây ra các thành phần để tái render:
CẬP NHẬT LẠI: Và javascript-fu của tôi rất kém, quá. Tôi đã không hoàn toàn nhận ra rằng bằng cách trở về Object.assign (state, {resources: action.payload.data });
Tôi đã trong thực tế, đột biến nhà nước, và rằng một đảo ngược đơn giản của các đối số sẽ cho tôi đạt được những gì tôi dự định. Nhờ có this discussion trên SO để khai sáng.
bạn đã thử thêm khóa vào đối tượng giảm gốc? 'const rootReducer = combinedReducers ({ điều hướng: navigationReducer, tài nguyên: resourcesReducer });' – anoop