A
A
Arti-Jack2018-04-25 23:09:35
JavaScript
Arti-Jack, 2018-04-25 23:09:35

Why does combineReducers throw an error?

I had such a difficulty that I do not understand some points in the editor.
First of all. I have two components.
First:

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)

Second
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)

There is an App component, it uses li-key to render the messages entered by the user as a list. Used in li-key by another child component - Content. Both of them are connected to the storage. And yet, I can’t combine reducers.
Well, for example:
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)

But the application crashes and issues:
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 | )

For some reason, he does not see the passed state :/
but if you combine both reducers into one like this:
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;
  }
}

That adding records works, but not deleting. I don’t know how to get the index of the passed element in li-key, I get the value through this.props.value, I can’t get the key like that.
In general, I don’t know where I screwed up here, I’ll be very happy if you tell me what’s wrong

Answer the question

In order to leave comments, you need to log in

1 answer(s)
U
User Unknown, 2018-04-25
@Arti-Jack

the first thing that catches your eye:
addTask , deleteTask - there is no point in such reducers, it's just a design mistake in your application. Why make a deleteTask reducer , and process the "DELETE_TASK" action in it , etc? make one task reducer, and check actions in it: ADD_TASK, DELETE_TASK .
Second, the error this.props.entryText.map is not a functionoccurs because this.props.entryText is the state you're trying to traverse with the .map. Now go and see what the structure of state.

{
  addTask: [...],
  deleteTask: [...]
}

You are confused with combineReducers because you don't know what this method does. In order to understand, implement this method yourself.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question