我是Redux的新手,如何在我的reducer中引用嵌套数组的状态?
这是我的状态:
const initState = {
tabs: [
{ arr: [] },
{ arr: [] }
]
};
我尝试做类似的事情:
tabs[0].arr: //do stuff
在我的reducer内,但出现解析错误。在第一个标签中引用数组的正确方法是什么?
编辑: 我将添加更多代码以提高清晰度
function reducer(state = initState, action) {
if (action.type == 'ADD_ARR') {
return {
state.tabs[0].arr: [...state.tabs[0].arr, action.arr]
}
}
}
//I get this message: 'Parsing error: Unexpected token, expected ","' at the period between 'state' and 'tabs[0]'
其余的代码
const arrAction = { type: "ADD_ARR", arr: "hello" };
store.dispatch(arrAction);
答案 0 :(得分:1)
通过不直接更新数组来避免状态突变。您还需要传递要修改的数组的索引。
const arrAction = { type: "ADD_ARR", arr: "hello", index: 0 };
store.dispatch(arrAction);
function reducer(state = initState, action) {
if (action.type == 'ADD_ARR') {
const index = action.index;
const arr = [...state.tabs[index].arr, action.arr];
return {
...state,
tabs: [...state.tabs.slice(0, index),
Object.assign({}, state.tabs[index], { arr: [...arr] }),
...state.tabs.slice(index + 1)
]
};
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.0.3/react-redux.min.js"></script>
<script src="http://wzrd.in/standalone/uuid%2Fv1@latest"></script>
<div id="root"></div>
<script type="text/babel">
const { Provider, connect } = ReactRedux;
const { applyMiddleware, createStore, combineReducers } = Redux;
function addArr(payload) {
return { type: 'ADD_ARR', payload}
}
const initialState = {
tabs: [{ arr: [] }, { arr: [] }]
};
function rootReducer(state = initialState, action) {
if (action.type == 'ADD_ARR') {
const index = action.payload.index;
const arr = [...state.tabs[index].arr, action.payload.title];
return {
...state,
tabs: [
...state.tabs.slice(0, index),
Object.assign({}, state.tabs[index], { arr: [...arr] }),
...state.tabs.slice(index + 1)
]
};
}
return state;
}
const store = createStore(rootReducer);
const mapStateToProps = state => {
return { tabs: state.tabs };
};
function mapDispatchToProps(dispatch) {
return {
addExpense: expense => dispatch(addExpense(expense)),
addArr: e => dispatch(addArr(e))
};
}
const ConnectedList = ({ tabs, addExpense }) => {
const tab1 = tabs[0].arr;
const tab2 = tabs[1].arr;
return (
<div>
{tab1.length > 0 && <p>tabs [0] arr values</p>}
<ul className="list-group list-group-flush">
{tab1.map((el, index) => (
<li className="list-group-item" key={index}>
{el}
</li>
))}
</ul>
{tab2.length > 0 && <p>tabs [1] arr values</p>}
<ul className="list-group list-group-flush">
{tab2.map((el, index) => (
<li className="list-group-item" key={index}>
{el}
</li>
))}
</ul>
</div>
);
};
const List = connect(mapStateToProps)(ConnectedList);
class StuffForm extends React.Component {
state = {
title: '',
};
handleSubmit = (index) => {
if (!this.state.title) {
return;
}
const { title} = this.state;
this.props.addArr({
title,
index
});
this.setState({
title: '',
});
};
handleInput = e => {
this.setState({
[e.target.name]: e.target.value
});
};
render() {
return (
<div>
<input
name="title"
placeholder="title"
onChange={this.handleInput}
value={this.state.title}
/>
<button onClick={() => this.handleSubmit(0)}>Add to arr[0]</button>
<button onClick={() => this.handleSubmit(1)}>Add to arr[1]</button>
</div>
);
}
}
const Form = connect(
null,
mapDispatchToProps
)(StuffForm);
class App extends React.Component {
render() {
return (
<div>
<List />
<Form />
</div>
);
}
}
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
</script>
答案 1 :(得分:0)
您的语法对于更新数组是错误的。
function reducer(state = initState, action) {
if (action.type == 'ADD_ARR') {
return {
tabs: [ {
arr: action.arr
}, ...state.tabs]
}
}