How to use a method in render reactjs?

0

i have a method set_data which is used to set data based on id. I know it could be easy to call this set_data in componentdidupdate when id changes. However in doing so it doesnt set some state variables in the parent component.

To get rid of that want to call set_data method in render . However since this set_data method sets state of data it enters into an infinite loop in render . Also cannot provide a condition (like prevprops.id!== this.props.id) to execute set_data method.

To prevent it thought of using this set_data method not to set state at all. and can call this set_data method in render. Below is the code,

export default class child extends React.Component {
state = {
    query: '',
    data: null,
};
empty_id = 0xffffffff;

componentDidMount() {
    this.set_open_data();
}

componentDidUpdate(prevProps) {
   if (prevProps.id !== this.props.id) {
        this.set_data();
   }
}

set_data = () => {
    if (!this.props.info) {
        return;
    }
    if (this.props.id === this.empty_id) {
        this.setState({data: null});
        return;
    }

    let data = {
        info: [],
        values: [],
    };
    const info = this.props.info;
    for (let i=0, ii=info.length; i < ii; i++) {
        if (info[i].meshes.includes(this.props.id)) {
            const info = info[i].info;
            const values = info[i].values;
            data = {
                info: typeof info === 'string' ? info.split('\r\n') : [],
                values: values ? values : [],
            };
            break;
        }
    }
    this.setState({data: this.filter_data(data, this.state.query)});
  };
  render = () => {
      const shown_data= this.state.data;  
      /* i want to call set_data method here*/};}

Could someone help me solve this. Thanks.

reactjs
asked on Stack Overflow Mar 8, 2019 by stackoverflow_user • edited Mar 8, 2019 by stackoverflow_user

1 Answer

0
  1. You can't call setData there, because that would be anti-pattern. It will trigger a loop that will continuously render as well as keeps setting state.
  2. You can probably rewrite the component this way:
export default class child extends React.Component {
  state = {
     query: ''
  };
  empty_id = 0xffffffff;

  componentDidMount() {
    this.set_open_data();
  }

  set_data = () => {
    let data = {};
    if (!this.props.info) {
      return data;
    }
    if (this.props.id === this.empty_id) {
      return data;
    }

    let data = {
      info: [],
      values: [],
    };
    const info = this.props.info;
    for (let i=0, ii=info.length; i < ii; i++) {
        if (info[i].meshes.includes(this.props.id)) {
            const info = info[i].info;
            const values = info[i].values;
            data = {
                info: typeof info === 'string' ? info.split('\r\n') : [],
                values: values ? values : [],
            };
            break;
        }
    }
    data = this.filter_data(data, this.state.query);
    return data;
  };

  render = () => {
      const shown_data= this.state.data; 
      const data = this.set_data(); 
      /* i want to call set_data method here*/};}

In this, we are not setting data in the state. For every new ID, it will get new data and will compute it from render thereby avoiding antipattern. I have also removed componentDidMount, since we are doing computation in render. Note: This solution means taking away data from the state, if you are not using data anywhere before render, this will work.

Let me know if this helps.

answered on Stack Overflow Mar 8, 2019 by Avanthika

User contributions licensed under CC BY-SA 3.0