在 React Native 中聚焦屏幕时如何正确更新状态变量?

问题描述 投票:0回答:1

我的 React Native 项目中有一个状态变量。当调用特定函数时需要更新它。然而,

setState
方法是异步的,导致我的变量在应该更新之后被更新。

我需要发生的是:

  • 屏幕以所述变量作为空数组开始;
  • 当屏幕聚焦时,填充数组,并根据数组在屏幕上创建组件;

发生的事情是:

  • 屏幕以所述变量作为空数组开始;
  • 当屏幕聚焦时,我尝试使用
    setState
    ;
  • 填充数组
  • 尝试创建组件时,由于数组为空,所以什么也没有发生;
  • 数组在页面构建后填充。

为了说明这是如何管理的,这就是我的代码:

const MyComponent: FC<MyComponentProps> = ({/*my component props*/}) => {
  const [rows, setRows] = useState<Array<boolean>>([]);

  useEffect(() => {
    console.log('rows on useEffect: ', rows);
  }, [rows]);

  async function OnFocus(): Promise<void> {

    await GetApplication();
  }

  async function GetApplication(): Promise<void> {
      const _state: ApplicationParameters = await ctrl.getApplicationParameters(
        ctrl.ctrl.getDevice()
      );
      
      console.log('_state.rows: ', _state.rows);
      console.log('rows before setRows()', rows);
      setRows(_state.rows!);

      console.log('rows after setRows()', rows);
    }

    return(
        <RowBars theme={theme} rows={rows} />
    )
}
 

上述代码的日志显示:

LOG  _state.rows:  [true, true, true, true, true, true, true, true, true, true, true]
LOG  rows before setRows() []
LOG  rows after setRows() []
LOG  rows on useEffect() [true, true, true, true, true, true, true, true, true, true, true]
LOG  rows on useEffect() [true, true, true, true, true, true, true, true, true, true, true]

如果稍后触发状态更新,数组会显示已满,但不会构建任何内容。

我的变量后面用到的组件如下:

interface RowBarsProps {
  theme: AppColors;
  rows: Array<boolean>;
}

export const RowBars: FC<RowBarsProps> = ({ theme, rows }: RowBarsProps) => {
  const [Rows] = useState<number>(rows.length);

  const _rows = [];
  for (let i = 0; i < Rows; i++) {
    _rows.push(<RowBar theme={theme} isOn={rows[i]} />);
  }

  return <RowToRowLiteBars>{_rows}</RowToRowLiteBars>;
};

我尝试过:

  • rows
    上更新
    useEffect
    。但是,我没有可靠的变量来观察
    useEffect
    ;
  • 的依赖数组
  • 从继承的 props 变量初始化行。但是,因为当
    rows
    更新时,props 变量尚未更新,所以它会尝试从未定义的值设置
    rows
reactjs typescript react-native react-hooks state
1个回答
0
投票

仔细查看我的代码,我发现问题出在子组件上。发生的事情是,它并不是为了感知父组件中的变化而构建的。

我所做的是创建一个

useEffect()
来观察即将到来的
rows
的变化。

不知道这是否是最佳实践,但它确实有效。

export const RowBars: FC<RowBarsProps> = ({ theme, rows }: RowBarsProps) => {
  const [rowBars, setRowBars] = useState<RowBarsState>([]);

  // Updates the row bars according to `rows` current state
  useEffect(() => {
    setRowBars(() => {
      const newRowBars = rows.map((row) => <RowBar theme={theme} isOn={row} />);
      return newRowBars;
    });
  }, [rows, theme]);

  return <RowToRowLiteBars>{rowBars}</RowToRowLiteBars>;
};
© www.soinside.com 2019 - 2024. All rights reserved.