मेरा प्रश्न: मेरे अपरिवर्तनीय स्थिति (मानचित्र) में किसी सरणी में किसी ऑब्जेक्ट की संपत्ति को अपडेट क्यों नहीं किया जा रहा है, जिससे रेडक्स मेरे घटक को अपडेट नहीं कर सकता है?रेडक्स घटकों को अद्यतन नहीं कर रहा है जब गहरे अपरिवर्तनीय राज्य गुण अपडेट किए जाते हैं
मैं (मेरे UploaderReducer अंदर से आप नीचे देख होगा) वस्तु इस तरह दिखता है एक विजेट है कि मेरे सर्वर पर फ़ाइलें अपलोड करता है, और मेरी प्रारंभिक अवस्था बनाने के लिए कोशिश कर रहा हूँ:
let initState = Map({
files: List(),
displayMode: 'grid',
currentRequests: List()
});
मैं एक thunk है एक घटना होती है जब एक घटना होती है (जैसे एक प्रगति अद्यतन) अपलोड करता है और क्रियाओं को प्रेषित करता है। उदाहरण के लिए, onProgress घटना इस तरह दिखता है:
export default UploaderReducer = handleActions({
// Other actions...
FILE_UPLOAD_PROGRESS_UPDATED: (state, { payload }) => (
updateFilePropsAtIndex(
state,
payload.index,
{
status: FILE_UPLOAD_PROGRESS_UPDATED,
progress: payload.progress
}
)
)
}, initState);
और updateFilePropsAtIndex
की तरह दिखता है:
onProgress: (data) => {
dispatch(fileUploadProgressUpdated({
index,
progress: data.percentage
}));
}
मैं बना सकते हैं और अपने कार्यों को संभालने के लिए redux-actions
उपयोग कर रहा हूँ, ताकि कार्रवाई के लिए मेरी कम करने इस तरह दिखता है :
export function updateFilePropsAtIndex (state, index, fileProps) {
return state.updateIn(['files', index], file => {
try {
for (let prop in fileProps) {
if (fileProps.hasOwnProperty(prop)) {
if (Map.isMap(file)) {
file = file.set(prop, fileProps[prop]);
} else {
file[prop] = fileProps[prop];
}
}
}
} catch (e) {
console.error(e);
return file;
}
return file;
});
}
अब तक, यह सब लगता ठीक से काम करने के लिए! Redux DevTools में, यह अपेक्षित कार्रवाई के रूप में दिखाई देता है। हालांकि, मेरे घटकों में से कोई भी अपडेट नहीं है! files
सरणी के लिए नए आइटम जोड़ना फिर से renders नई फ़ाइलें के साथ मेरी यूआई, जोड़ा तो Redux निश्चित रूप से एक समस्या नहीं है मुझे ऐसा करने के साथ ...
मेरे शीर्ष स्तर घटक connect
दिखता का उपयोग कर दुकान से कनेक्ट होता है इस तरह:
const mapStateToProps = function (state) {
let uploadReducer = state.get('UploaderReducer');
let props = {
files: uploadReducer.get('files'),
displayMode: uploadReducer.get('displayMode'),
uploadsInProgress: uploadReducer.get('currentRequests').size > 0
};
return props;
};
class UploaderContainer extends Component {
constructor (props, context) {
super(props, context);
// Constructor things!
}
// Some events n stuff...
render(){
return (
<div>
<UploadWidget
//other props
files={this.props.files} />
</div>
);
}
}
export default connect(mapStateToProps, uploadActions)(UploaderContainer);
uploadActions
redux-actions
उपयोग कर बनाई गई कार्रवाई के साथ एक वस्तु है।
files
सरणी में एक file
वस्तु मूल रूप से यह है:
{
name: '',
progress: 0,
status
}
UploadWidget
मूल रूप से एक खींचें n ड्रॉप div और एक files
सरणी स्क्रीन पर मुद्रित है।
मैं redux-immutablejs
का उपयोग कर मदद करने के लिए के रूप में मैं GitHub पर कई पदों में देखा है की कोशिश की, लेकिन मैं अगर यह मदद करता है पता नहीं है ... यह मेरा जड़ कम करने है:
import { combineReducers } from 'redux-immutablejs';
import { routeReducer as router } from 'redux-simple-router';
import UploaderReducer from './modules/UploaderReducer';
export default combineReducers({
UploaderReducer,
router
});
मेरा ऐप प्रवेश बिंदु इस तरह दिखता है:
const store = configureStore(Map({}));
syncReduxAndRouter(history, store, (state) => {
return state.get('router');
});
// Render the React application to the DOM
ReactDOM.render(
<Root history={history} routes={routes} store={store}/>,
document.getElementById('root')
);
अन्त में, मेरी <Root/>
घटक इस तरह दिखता है:
import React, { PropTypes } from 'react';
import { Provider } from 'react-redux';
import { Router } from 'react-router';
export default class Root extends React.Component {
static propTypes = {
history: PropTypes.object.isRequired,
routes: PropTypes.element.isRequired,
store: PropTypes.object.isRequired
};
get content() {
return (
<Router history={this.props.history}>
{this.props.routes}
</Router>
);
}
//Prep devTools, etc...
render() {
return (
<Provider store={this.props.store}>
<div style={{ height: '100%' }}>
{this.content}
{this.devTools}
</div>
</Provider>
);
}
}
तो, अंत में, अगर मैं निम्नलिखित राज्य वस्तु में एक 'प्रगति' अद्यतन करने के लिए प्रयास करते हैं,/Redux मेरी घटकों को अपडेट नहीं करता प्रतिक्रिया:
{
UploaderReducer: {
files: [{progress: 0}]
}
}
ऐसा क्यों है? मैंने सोचा कि Immutable.js का उपयोग करने का पूरा विचार यह था कि संशोधित वस्तुओं की तुलना करना आसान था, भले ही आप उन्हें कितनी गहराई से अपडेट करते हैं? How to use Immutable.js with redux? https://github.com/reactjs/redux/issues/548
हालांकि, अपरिवर्तनीय का उपयोग कर के बताया लाभ इस लड़ाई के लायक होने लगते हैं और मैं आंकड़ा करने में खुशी होगी:
यह आम तौर पर Redux के साथ काम करने अपरिवर्तनीय हो रही लगता है के रूप में यह लगता है के रूप में सरल नहीं है क्या मैं गलत कर रहा हूँ!
अद्यतन अप्रैल 10 वर्ष 2016 चयनित जवाब ने मुझे बताया मैं गलत और पूर्णता के लिए के लिए क्या कर रहा था, मेरे updateFilePropsAtIndex
समारोह अब शामिल बस इस:
return state.updateIn(['files', index], file =>
Object.assign({}, file, fileProps)
);
यह पूरी तरह से अच्छी तरह से काम करता है! :) पहले
जब आप कहते हैं कि "घटक नहीं किया जा रहा है अपडेट किया गया "क्या आपका मतलब है कि इसे रेडक्स से नए प्रोप नहीं मिल रहे हैं? क्या MapStateToProps को अद्यतन प्रगति प्राप्त नहीं होती है?Reducer के बारे में, क्या कार्रवाई पेलोड में सही प्रगति है? – azium
अपलोडरकंटनर mapStateToProps फ़ंक्शन बिलकुल नहीं है, राज्यों को अपेक्षित मूल्यों के साथ DevTools में अपडेट किए जाने के बावजूद। मेरे पास यूनिट परीक्षणों की जांच है कि मैं जो कर रहा हूं वह काम करना चाहिए, इसलिए मुझे ऐसा लगता है कि रेडक्स स्तर पर मुझे कुछ समझ नहीं आ रहा है, लेकिन मुझे नहीं पता कि यह क्या है! –
क्या आप जेएसबीन पर ऑनलाइन काम कर रहे उदाहरण प्राप्त कर सकते हैं? यह काम करना आसान हो गया है। – whitep4nther