I wrote functional component with react native.
but I’m in trouble because of a strange problem that seems to be a bug.
My purpose is changing variable in react functional component,
but variable not changed.
–I know It will be solved with change
let isDirty
to
cosnt [isDirty,setIsDirty] = useState(false)
Why doesn’t "isDirty" change when the handleTitleChange event occurs?
In pure js, it works very well
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
pure js
const Update = () => {
let isDirty=false;
const handleTitleChange=(txt)=>{
console.log(isDirty);
isDirty=true;
console.log(isDirty);
}
handleTitleChange("a");
handleTitleChange("b");
};
Update();
I declare then outside the functions… work’s rsrs
but aways use useState()! just use let in case you don’t needs to render in JSX and needs that the variable change instantaneous.
And bee carefoul, if you have 2 or more of this component, will be only one global let variable for all.
React does not re-render the component if any of the values other than the state changes, so, basically even if
isDirty
is updated, you won’t see it in effect since the component doesn’t realize there has been an update to one of its variables.When the component re-renders, it executes the
let isDirty=false
again and this overwrites your updateconverting as state like so, and updating the functions can solve your problem
Read more about state
isDirty
is neither aprop
nor astate
. So it doesn’t persist. On re-render, it will initialize back tofalse
.Make it a
state
instead.