Home > Blockchain >  How do you set the state of a component pre render?
How do you set the state of a component pre render?

Time:09-14

I am passing props to a react component using TSX and want to set the state of the component to be the values of the props, however it is not setting the state. I printed to the console the values of props and state.

Props returns the array of objects that I want like this: [{...},{...},{...}], whereas printing the state just returns an empty array.

I have tried the following, but neither one of them works:

Attempt 1:

 export interface IStats {
    id: string,
    count: number,
    avgDuration: number,
    visits: Array<IVisits>
}

export interface IVisits {
    id: string,
    views: number,
    browser: string,
    channel: string
}

export class SummaryComponent extends React.Component<IStats> {

    state = {
        value: this.props.visits
    }

    constructor(props: IStats) {
        super(props);
    }

    public render(): React.ReactNode {
        const { value } = this.state;
        return (
            <div>
                <button onClick={() => {console.log(this.props.visits)}}>Props</button>
                <button onClick={() => {console.log(this.state.value)}}>State</button>
                <button onClick={() => {console.log(value)}}>Value</button>
            </div>
        )
    }
}

Attempt 2:

export interface IStats {
    id: string,
    count: number,
    avgDuration: number,
    visits: Array<IVisits>
}

export interface IVisits {
    id: string,
    views: number,
    browser: string,
    channel: string
}

export class SummaryComponent extends React.Component<IStats> {
    constructor(props: IStats) {
        super(props);

        this.state = {
            value: this.props.visits
        };
    }

    public render(): React.ReactNode {
        const { value } = this.state;
        return (
            <div>
                <button onClick={() => {console.log(this.props.visits)}}>Props</button>
                <button onClick={() => {console.log(this.state.value)}}>State</button>
                <button onClick={() => {console.log(value)}}>Value</button>
            </div>
        )
    }
}

This throws the following error: Property 'value' does not exist on type 'Readonly<{}>

Is there something I am missing?

CodePudding user response:

React.Component<IStats>

React.Component accepts two parameters in its generic. The first is the props, the second is the state. Since you havn't specified the state, the default is used, which is that the state is an empty object, and empty objects have no .value property.

To fix this, add the type for the state:

interface SummaryComponentState {
  value: Array<IVisits>
}

export class SummaryComponent extends React.Component<IStats, SummaryComponentState> {

CodePudding user response:

I'm no Typescript expert, but it looks like you need to declare the type of your state object's value property.

From this article:

To solve the React.js error "Property does not exist on type 'Readonly<{}>'", make sure to explicitly type the props or state object of the class, adding any of the properties you intend to access on the props or state objects.

  • Related