dropWizard
dropWizard

Reputation: 3538

React: passing in properties

I am trying to pass in store as a property to AddTodo but I am getting the error: Cannot read property 'todos' of undefined

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux'
import { connect } from 'react-redux'
import { createStore } from 'redux'

const todo = (state, action) => {
    switch (action.type) {
        case 'ADD_TODO':
            return {
                id: action.id,
                text: action.text
            }
        default:
            return state
    }
}

const todos = (state = [], action) => {
    switch (action.type) {
        case 'ADD_TODO':
            return [
                ...state,
                todo(undefined, action)
            ];
        default:
            return state
    }
}

let store = createStore(todos)


let nextTodoId = 0
const AddTodo = () => {
    let input;

    //this works
    console.log(store.getState())
    //this doesn't
    console.log(this.props.todos)


    return (
        <div>
            <input ref={node => {input = node}}/>
            <button onClick = {() => {
                store.dispatch({
                    type: 'ADD_TODO',
                    id: nextTodoId++,
                    text: input.value
                });
                input.value = ''
            }}>
                Add Todo
            </button>



        </div>
    )
};

store.subscribe(AddTodo)


ReactDOM.render(
    <AddTodo 
        todos={store.getState()}
    />,
    document.getElementById('root'));

I am a little confused why I am getting the error when printing this.props.todos. I thought I was passing in todos as a prop in <AddTodo todos={...}/>

Upvotes: 0

Views: 265

Answers (2)

Icepickle
Icepickle

Reputation: 12796

Functional components work differently, they don't have a context of this, but their props are passed through the arguments of the function

To make it work, just change your function call of addToDos, like this:

const AddTodo = (props) => {
  let input;
  console.log(props.todos);
  return (/* and the rest of your code...*/) ;
};

For the rest, as Arun Ghosh is saying, you should revisit your subscribe pattern, for example like this

store.subscribe(() => {
    ReactDOM.render(
        <AddTodo 
           todos={store.getState()}
        />,
        document.getElementById('root'));
});

Upvotes: 2

Arun Ghosh
Arun Ghosh

Reputation: 7734

You should pass the store object and subscribe for changes

store.subscribe(() => {
  // In our case the state will be updated when todos are set
  console.log(store.getState().todos);
});

Upvotes: 0

Related Questions