4

I cannot figure out how to set the state of my React component with TypeScript.

  • I'm making a simple Todo list
  • I have a component for the entire list: TodoList
  • I want to seed the list with some items to play around with
  • I figured I'd send in a simple array as the props to the TodoList component, and then immediately set that as the state so I have something to work off of
import * as React from "react";
import { TodoItem, ITodoItem } from "../TodoItem";

interface ITodoListProps {
    items: ITodoItem[];
}

interface ITodoListState {
    stateItems: ITodoItem[];
}

export class TodoList extends React.Component<ITodoListProps, Partial<ITodoListState>> {
    constructor(props: ITodoListProps) {
        super(props);

        // Trouble figuring this part out
        //  I'd like to set the state to the list from the 
        //  props, as a seed.
        this.setState({
            stateItems: this.state.stateItems
        });
    }

    public render() {
        return (
            <div>
                <ul>
                    // This should probably be displaying the items from the state, and not the props.
                    {this.props.items.map((todo, i) => {
                        return <TodoItem key={i} name={todo.name} />
                    })}
                </ul>
            </div>
        );
    }
}

2 Answers 2

4

You need to pass the props.items to the state when constructing the initial state:

export class TodoList extends React.Component<ITodoListProps, Partial<ITodoListState>> {
    constructor(props: ITodoListProps) {
        super(props);

        this.state = {
            stateItems: props.items
        };
    }
    ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way to do this without always having to write super(props) and props:ITodoListProps? It’s just boilerplate which shouldn’t be necessary but if I assign to state outside of the constructor it seems to lose type safety…
@binki You must call super, it's a javascript thing: "If there is a constructor present in subclass, it needs to first call super() before using "this"" (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…). As for the props, if you want the compiler to know the types you need to specify them.
3

In the constructor when setting the initial state, simply assign the value you want to this.state:

constructor() {
  // ...
  this.state = { stateItems: ... /* initial value */ }
}

Later in the lifecycle methods or event listeners you can change the state the way you are doing it in the constructor with setState

1 Comment

I think this could be improved by showing the call to super and passing of props. People might think you’re implying that it’s not necessary.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.