Состояние редукса не создается должным образом в редукторах - PullRequest
0 голосов
/ 26 декабря 2018

Я создаю простое приложение для контактов, используя React и Redux.Мой объект состояния выглядит следующим образом:

{
  "contacts": [
    {
      "name": "Miguel Camilo",
      "phone": "123456789"
    },
    {
      "name": "Peter",
      "phone": "883292300348"
    },
    {
      "name": "Jessica",
      "phone": "8743847638473"
    },
    {
      "name": "Michael",
      "phone": "0988765553"
    }
  ],
  "activeContact": {
    "name": "Peter",
    "phone": "883292300348"
  }
}

Я пытаюсь создать функцию добавления контактов, которая будет брать имя и номер из входных данных на странице и добавлять их в массив contacts в состоянии,Вот как это построено:

Компонент ContactsList:

class ContactList extends Component {
  renderList() {
    return this.props.contacts.map((contact) => {
      return (
        <li
          key={contact.phone}
          onClick={() => this.props.selectContact(contact)}
          className='list-group-item'>{contact.name}</li>
      );
    });
  }
  render() {
    return (
      <ul className = 'list-group col-sm-4'>
        {this.renderList()}
      </ul>
    );
  }
}

function mapStateToProps(state) {
  return {
    contacts: state.contacts
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ selectContact: selectContact }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(ContactList)

AddContactsComponent:

class AddContactModal extends Component {

  constructor() {
    super();
    this.state = {firstName: "", phone: ""};
  }

  handleNameChange(event) {
    this.setState({firstName: event.target.value})
  }

  handlePhoneChange(event) {
    this.setState({phone: event.target.value});
  }

  render() {

    return(
      <div>
        <input type="text" className="name" placeholder="Contact Name" onChange={(event) => this.handleNameChange(event)}/>
        <input type="text" className="phone" placeholder="Contact Phone" onChange={(event) => this.handlePhoneChange(event)}/>
        <AddContactButton firstName={this.state.firstName} firstName={this.state.phone} onClick={() => this.props.addContact({"name": this.state.firstName, "phone": this.state.phone})}/>
      </div>
    );
  }
}

function mapStateToProps(state) {
  console.log('mapstatetoprops:');
  console.log(state);
  return {
    contacts: state.contacts
  };
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({ addContact: addContact }, dispatch);
}

export default connect(mapStateToProps, mapDispatchToProps)(AddContactModal)

Редуктор контактов (содержащий обработчик ADD_CONTACT):

export default function (state = { contacts : [] }, action) {

  switch (action.type) {
    case 'ADD_CONTACT':
      console.log(state);
      return Object.assign({}, state, {
        contacts: state.concat([
          {
            name: action.payload.name,
            phone: action.payload.phone
          }
        ])
      })
    default:
      return state;
  }
}

Приложение index.js, в котором построен магазин:

const createStoreWithMiddleware = applyMiddleware()(createStore);
const initialState = {
  "contacts": [
    {
      "name": "Miguel Camilo",
      "phone": "123456789"
    },
    {
      "name": "Peter",
      "phone": "883292300348"
    },
    {
      "name": "Jessica",
      "phone": "8743847638473"
    },
    {
      "name": "Michael",
      "phone": "0988765553"
    }
  ],
  "activeContact": null
};

ReactDOM.render(
  <Provider store={ createStoreWithMiddleware(reducers, initialState) }>
   <App />
  </Provider>
, document.querySelector('.container'));

И объединение моих редукторов:

const rootReducer = combineReducers({
  contacts: ContactsReducer,
  activeContact: ActiveContactReducer
});

export default rootReducer;

Моя проблема заключается в том, что, когда я нажимаю на кнопку Добавить контакт, новыйМассив contacts добавляется в существующий массив contacts в состоянии, а затем по какой-то странной причине мой начальный список контактов добавляется на верхнем уровне состояния.Таким образом, после нажатия кнопки «Добавить контакт» (и до того, как произойдет ошибка), когда я регистрирую this.props.contacts, это выглядит следующим образом:

{
  "0": {
    "name": "Miguel Camilo",
    "phone": "123456789"
  },
  "1": {
    "name": "Peter",
    "phone": "883292300348"
  },
  "2": {
    "name": "Jessica",
    "phone": "8743847638473"
  },
  "3": {
    "name": "Michael",
    "phone": "0988765553"
  },
  "contacts": [
    {
      "name": "Miguel Camilo",
      "phone": "123456789"
    },
    {
      "name": "Peter",
      "phone": "883292300348"
    },
    {
      "name": "Jessica",
      "phone": "8743847638473"
    },
    {
      "name": "Michael",
      "phone": "0988765553"
    },
    {
      "name": "123",
      "phone": "123"
    }
  ]
}

Итак, новый массив contacts был добавлен в исходный contactsмассив, содержащий исходные значения плюс новое.Хотя исходный массив contacts остается неизменным.

Я не уверен, почему это так.Первоначально я думал, что объект state, передаваемый моему редуктору, является полным состоянием, но, похоже, это только часть моего состояния contacts, поэтому я изменил свой вызов Object.assign (), чтобы учесть это, изменив его.от contacts: state.contacts.concat() до contacts: state.concat(), но это все еще не решило проблему.

Я хочу, чтобы состояние, которое возвращается к моему компоненту ContactsList, выглядело так:

{
  "contacts": [
    {
      "name": "Miguel Camilo",
      "phone": "123456789"
    },
    {
      "name": "Peter",
      "phone": "883292300348"
    },
    {
      "name": "Jessica",
      "phone": "8743847638473"
    },
    {
      "name": "Michael",
      "phone": "0988765553"
    },
    {
      "name": "this is the new contact",
      "phone": "123"
    }
  ],
  "activeContact": {
    "name": "Peter",
    "phone": "883292300348"
  }
}

Только оригиналсостояние с одним дополнительным контактом, добавленным в мой массив contacts.Есть идеи, что не так с моей реализацией?Любая помощь приветствуется!

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Проблема в том, как вы назначаете свой initialState.Так как вы используете combReducers с одним ключом, являющимся контактами, ваши contactsReducers получают

[
    {
      "name": "Miguel Camilo",
      "phone": "123456789"
    },
    {
      "name": "Peter",
      "phone": "883292300348"
    },
    {
      "name": "Jessica",
      "phone": "8743847638473"
    },
    {
      "name": "Michael",
      "phone": "0988765553"
    }
  ],

, тогда как вы ожидаете, что оно будет

{
  contacts: [
    {
      "name": "Miguel Camilo",
      "phone": "123456789"
    },
    {
      "name": "Peter",
      "phone": "883292300348"
    },
    {
      "name": "Jessica",
      "phone": "8743847638473"
    },
    {
      "name": "Michael",
      "phone": "0988765553"
    }
  ]
}

Таким образом, изменение, которое вам нужно сделать, равно

export default function (state = [], action) {

  switch (action.type) {
    case 'ADD_CONTACT':
      console.log(state);
      return state.concat([
          {
            name: action.payload.name,
            phone: action.payload.phone
          }
      ])
    default:
      return state;
  }
}

После внесения вышеуказанных изменений все будет работать

0 голосов
/ 26 декабря 2018

вы должны изменить свое состояние следующим образом

export default function (state = { contacts : [] }, action) {

  switch (action.type) {
    case 'ADD_CONTACT':
      console.log(state);
      return {
       ...state,
       contacts: [...state.contacts, ...contacts]
      }
    default:
      return state;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...