react functional component let variable doesn't changed

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();

42 thoughts on “react functional component let variable doesn't changed”

  1. 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.

    let isDirty = false;
    
    export const Component = (props) => {
    
    }
    
    Reply
  2. 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 update

    converting as state like so, and updating the functions can solve your problem

    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})
      }
    

    Read more about state

    Reply
  3. isDirty is neither a prop nor a state. So it doesn’t persist. On re-render, it will initialize back to false.

    Make it a state instead.

    const [isDirty, setDirty] = useState(false)
    
    Reply

Leave a Comment