我用react native编写了功能组件。 但是我遇到了麻烦,因为一个奇怪的问题似乎是一个错误。
我的目的是更改反应功能组件中的变量, 但变量未更改。
-我知道它将通过改变得到解决
let isDirty
至
cosnt [isDirty,setIsDirty] = useState(false)
当handleTitleChange事件发生时,为什么“ isDirty”没有改变?
在纯js中,效果很好
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
const Update = () => {
let isDirty=false;
const handleTitleChange=(txt)=>{
console.log(isDirty);
isDirty=true;
console.log(isDirty);
}
handleTitleChange("a");
handleTitleChange("b");
};
Update();
答案 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