Arti-Jack
@Arti-Jack

Почему combineReducers вызывает ошибку?

У меня возникла такая трудность, что мне не понятны некоторые моменты в редаксе.

Во-первых. У меня есть два компонента.
Первый:
class App extends React.Component {
  onDoSomeStuff() {
   this.props.onAddTask(this.entryInput.value)
  }
  render() {
    //alert(this.props.entryText)
    return (
      <div>
        <input type='text' ref={ (input) => this.entryInput = input } placeholder='Add your task here...' />
        <Button onClick={this.onDoSomeStuff.bind(this)}>Add</Button>
        <ul>
          {
            /*
            this.props.entryText.map(
              (track, index) => 
               <li key={index}>{track}</li>
            )
            */
            this.props.entryText.map(
              (task, index) =>
                <Content key={index} value={task} />
            )
          }
        </ul>
      </div>
    )
  }
}

export default connect(state => ({entryText: state }), 
  dispatch => ({
    onAddTask: (taskName) => {
      dispatch({ type: 'ADD_TASK', payload: taskName });
    }
  })
)(App)


Второй
class Content extends React.Component {
  constructor(props) {
    super(props)
    this.contentId = parseInt(this.props.children)
  }

  onDoSomeStuff() {
    this.props.onDeleteTask(this.props.key)
    console.log("hmmm", this.props.index)
  }
  render() {
    //alert(this.props.entryText)
    return (
      <div>
         {console.log(this.props.value)}
        <b>{/*this.props.entryText[this.props.index*/this.props.value}</b>
        <button onClick={this.onDoSomeStuff.bind(this)}>Delete</button>
      </div>
    )
  }
}

export default connect(state => ({ }), 
  dispatch => ({
    onDeleteTask: (taskId) => {
      dispatch({ type: 'DELETE_TASK', payload: taskId });
    }
  })
)(Content)

Есть компонент App, он использует li-key, чтобы рендерить списком введенные пользователем сообщения. Используется в li-key другой дочерний компонент - Content. Оба они подключены к хранилищу. И ещё, у меня не выходит комбинировать редьюсеры.

Ну вот, например:

function addTask(state = [], action) {
  switch (action.type) {
    case 'ADD_TASK':
      return [...state,
      action.payload];
      break;
    
    default:
      return state;
  }
}



function deleteTask(state=[], action) {
	switch (action.type) {
		case 'DELETE_TASK':
			return state.filter(word => word !== state[action.id]);
			break;

		default:
			return state;
	}
}

var reducers = combineReducers({addTask, deleteTask})
var store = createStore(reducers)

Но приложение крашится и выдаёт:

TypeError: this.props.entryText.map is not a function
App.render
src/App.js:29
  26 |    <li key={index}>{track}</li>
  27 | )
  28 | */
> 29 | this.props.entryText.map(
  30 |   (task, index) =>
  31 |     <Content key={index} value={task} />
  32 | )

Он почему-то не видит переданный state.

Но если объединить оба редьюсера в один так:

function addTask(state = [], action) {
  switch (action.type) {
    case 'ADD_TASK':
      return [...state,
      action.payload];
      //return state.concat(action.payload)
      break;


      case 'DELETE_TASK':
      return state.filter(word => word !== state[action.payload]);
      break;

    
    default:
      return state;
  }
}

То добавление записей работает, но не удаление. Я не знаю как получить индекс переданного элемента в li-key, значение получаю через this.props.value, ключ так получить не могу.

В общем, не знаю где я тут накосячил, буду очень рад, если подскажите что не так.
  • Вопрос задан
  • 362 просмотра
Решения вопроса 1
AndrewN1
@AndrewN1
первое, что бросается в глаза:
var reducers = combineReducers(addTask, deleteTask)

.combineReducers принимает объект, т.е должно быть
var reducers = combineReducers({ addTask, deleteTask })

addTask, deleteTask - в таких редъюсерах смысла нет, это просто ошибка проектирования вашего приложения. Зачем делать редъюсер deleteTask, а в нем еще и экшен "DELETE_TASK" обрабатывать и т.д? сделайте один редъюсер tasks, а в нем уже проверяйте экшены: ADD_TASK, DELETE_TASK.

Второе, ошибка this.props.entryText.map is not a function возникает, потому что this.props.entryText -это и есть state, по которому Вы пытаетесь пройти с помощью .map. А теперь идите и посмотрите какая структура у state.
{
  addTask: [...],
  deleteTask: [...]
}

Вы запутались с combineReducers, потому что не знаете, что этот метод делает. Для того, чтобы разобраться, реализуйте этот метод сами.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы