反应功能组件,让变量保持不变

时间:2019-10-11 15:14:43

标签: javascript reactjs react-native

我用react native编写了功能组件。 但是我遇到了麻烦,因为一个奇怪的问题似乎是一个错误。

我的目的是更改反应功能组件中的变量, 但变量未更改。

-我知道它将通过改变得到解决 let isDirtycosnt [isDirty,setIsDirty] = useState(false)

当handleTitleChange事件发生时,为什么“ isDirty”没有改变?

在纯js中,效果很好

update.tsx

import React, { useState } from 'react';
import { View, TextInput, CheckBox, Button } from 'react-native';
import { NavigationInjectedProps } from 'react-navigation';
import TodoItem from '../models/todoItem';
import { updateItem } from '../DataProvider';

interface UpdateProps extends NavigationInjectedProps {
}

const Update: React.FC<UpdateProps> = (props) => {
  const [item, setItem] = useState(props.navigation.getParam("item") as TodoItem)
  let isDirty=false

  const handleSave=()=>{
    updateItem(item)

    if(isDirty&&props.navigation.state.params)
    {
      props.navigation.state.params.onUpdated(item);
    }
    props.navigation.goBack();
  }

  const handleCompleteChange= (value:boolean)=>{
    isDirty=true
    setItem({...item,isComplete:value})
  }

  const handleTitleChange=(txt:string)=>{
    isDirty=true
    setItem({...item,title:txt})
  }

  const handleContentChange=(txt:string)=>{
    isDirty=true
    setItem({...item,contents:txt})
  }

  return <View>
    <CheckBox value={item.isComplete} onValueChange={handleCompleteChange}></CheckBox>
    <TextInput defaultValue={item.title} onChangeText={handleTitleChange}></TextInput>
    <TextInput defaultValue={item.contents} onChangeText={handleContentChange}></TextInput>
    <Button title="Save" onPress={handleSave}></Button>
  </View>;
};

export default Update

纯js

const Update = () => {
  let isDirty=false;

  const handleTitleChange=(txt)=>{
    console.log(isDirty);
    isDirty=true;
    console.log(isDirty);
  }
  handleTitleChange("a");
  handleTitleChange("b");
};


Update();

3 个答案:

答案 0 :(得分:2)

isDirty既不是prop也不是state。因此它不会持续存在。重新渲染后,它将初始化回false

改为使用state

const [isDirty, setDirty] = useState(false)

答案 1 :(得分:1)

在编写函数式 React 代码时,useRef 是保存可变值的实际候选者,这些值保存数据并且在使用函数式组件时也不会导致重新渲染。

直接反应docs

useRef() is useful for more than the ref attribute. It’s handy for keeping any mutable value around similar to how you’d use instance fields in classes.

要使用 useRef 解决您的问题,您需要这样做:

const isDirty = useRef(false);

...

const handleCompleteChange= (value:boolean)=>{
    isDirty.current = true;
    setItem({...item, isComplete:value})
}


React 团队的动机是完全删除基于类的概念,这会给开发人员带来混乱。 以下是您可以阅读的内容:https://reactjs.org/docs/hooks-intro.html#motivation

答案 2 :(得分:0)

如果状态以外的任何其他值发生变化,React都不会重新呈现组件,因此,基本上,即使isDirty被更新,您也不会看到它有效,因为组件没有意识到其中一个变量已更新。

重新渲染组件时,它将再次执行let isDirty=false,这将覆盖您的更新

像这样转换为状态,并更新功能可以解决您的问题

const [isDirty, setIsDirty] = useState(false);

 const handleCompleteChange= (value:boolean)=>{
    setIsDirty(true);
    setItem({...item,isComplete:value})
  }

  const handleTitleChange=(txt:string)=>{
    setIsDirty(true);
    setItem({...item,title:txt})
  }

  const handleContentChange=(txt:string)=>{
    setIsDirty(true);
    setItem({...item,contents:txt})
  }

详细了解state