te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - React: How can I call a method only once in the lifecycle of a component, as soon as data.loading is false - Stack
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React: How can I call a method only once in the lifecycle of a component, as soon as data.loading is false - Stack

programmeradmin3浏览0评论

I have a React ponent with a prop 'total' that changes every time the ponent is updated:

function MyView(props) {
  const total = props.data.loading ? 0 : props.data.total;
  return (
    <p> total </p>
  );
}

The first time the ponent mounts the total is say 10. Every time the ponent is updated because of a prop change the total goes up.

Is there a way I can display the original total (in this example 10)?

I have tried setting it in this.total inside ponentDidMount, but props.data.total is not yet available when ponentDidMount is called. Same with the constructor. The total only bees available when props.data.loading is false.

I have a React ponent with a prop 'total' that changes every time the ponent is updated:

function MyView(props) {
  const total = props.data.loading ? 0 : props.data.total;
  return (
    <p> total </p>
  );
}

The first time the ponent mounts the total is say 10. Every time the ponent is updated because of a prop change the total goes up.

Is there a way I can display the original total (in this example 10)?

I have tried setting it in this.total inside ponentDidMount, but props.data.total is not yet available when ponentDidMount is called. Same with the constructor. The total only bees available when props.data.loading is false.

Share Improve this question asked Jun 29, 2018 at 14:46 Alina BoghiuAlina Boghiu 1031 gold badge1 silver badge6 bronze badges 1
  • You can render 0 if data loading or props.data.total if not – Kasabucki Alexandr Commented Jun 29, 2018 at 14:51
Add a ment  | 

5 Answers 5

Reset to default 3

In order to get access to lifecycle features, you must move from function, stateless ponent, to a class ponent.

in the below example, InitialTotal is initialized in the construstor lifecycle method and it never changes.

currentTotal, is incremented each time the render function is called - when the ponent is re-rendered (because of props change or state changes)

it should look something like that:

class MyView extends React.Component {
  constructor(props) {
    super(props)

    this.initialTotal = 10;
    this.currentTotal = 10;
  }
  render() {
    this.currentTotal+=1;
    return (
      <p>InitialToal: {this.initialTotal}</p>
      <p>Current Total: {this.currentTotal}</p>
    );
  }
}   

You could create a stateful ponent and store the initial total in the ponent state.

Example

class MyView extends React.Component {
  state = {
    initialTotal: this.props.total
  };
  render() {
    const { total } = this.props;
    const { initialTotal } = this.state;
    return (
      <div>
        <p> Total: {total} </p>
        <p> Initial total: {initialTotal} </p>
      </div>
    );
  }
}
class App extends React.Component {
  state = {
    total: 10
  };

  ponentDidMount() {
    this.interval = setInterval(() => {
      this.setState(({ total }) => {
        return { total: total + 1 };
      });
    }, 1000);
  }

  ponentWillUnmount() {
    clearInterval(this.interval);
  }

  render() {
    return <MyView total={this.state.total} />;
  }
}

If I understand your requirements correctly...

function MyView(props) {
      // if you only need to set the value once on load just use useState.
      // the const total will be the value you pass in to useState.
      const [total, setTotal] = useState(props.data.loading ? 0 : props.data.total)

      // if its possible that the value is not available on initial load and
      // you want to set it only once, when it bees available, you can use 
      // useEffect with useState
      useEffect(() => {
        // some condition to know if data is ready to set
        if (!props.data.loading) {
          setTotal(props.data.total)
        }

      }, [props.data.total, setTotal, props.data.loading] 
      // this array allows you to limit useEffect to only be called when 
      // one of these values change. ( when total changes in this case, 
      // as the const function setTotal will not change 
      // ( but react will fuss if its used and not in the list ).

      return (
        <p> {total} </p>
      );
    }

I have the same need. With a functional ponent, I need to store the inital snapshot of states, let user play with different state values and see their results immediately, eventually, they can just cancel and go back to the initial states. Apply the same structure to your problem, this is how it looks:

import React from 'react';
import { useEffect, useState } from "react";

const TestView = (props: { data: any }) => {
    // setting default will help type issues if TS is used
    const [initialTotal, setInitialTotal] = useState(props.data.total)

    useEffect(() => {
        // some condition to know if data is ready to set
        setInitialTotal(props.data.total);
        // Critical: use empty array to ensure this useEffect is called only once.       
    }, [])

    return (
        <div>
        <p> { initialTotal } </p>
        <p> { props.data.total } </p>
        </div>
    );
}

export default TestView

You can use getDerivedStateFromProps life cycle method.

static getDerivedStateFromProps(props, state){

        if(props.data.total && (props.data.total==10)){
             return {
                 total : props.total // show total only when its 10
              }
         }else{
             return null; // does not update state
          }
    }

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论