减速器:更新数组中的数组

时间:2019-05-26 15:57:42

标签: reactjs redux

我是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);

2 个答案:

答案 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]
  }
}