Wimal Weerawansa
Wimal Weerawansa

Reputation: 157

React function component not updating with new props

I have React function component Input it's a simple input field it takes only one prop named epoch, the value of epoch in milliseconds. inside the component, I use moment js to format this time to a HH:mm (hour:min) format, also I'm using useState inside the Input component to set input value while user updates the input I needed to check with complex algorithms and need to append +/- with number.

Input.jsx

import React, {useState, } from 'react'
import moment from 'moment'

function Input({epoch}){
  console.log(epoch)
  const translateValueToString = epochValue => {
    return moment(epochValue).format('HH:mm')
  }
  const [value, updateValue] = useState(translateValueToString(epoch))
  return <input value={value} onChange={(e) => {
    // i need to update the value with some complex calculation and update it
    updateValue(`${e.target.value}+2`)
  }}/>
}

export default Input

As you can see, I'm using the Internal state to update the value of the input, instead use directly use the prop, because I needed to join some string to the value while user types.

From parent Component, I'm sending epoch value as prop aslo in paren component I have button to update epoch value with +1 minute for each click.

App.jsx

import React, {useState} from "react";
import "./styles.css";
import Input from './Input'
import moment from 'moment'

export default function App() {
  const [epoch, updateEpoch] = useState(moment().valueOf())
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <Input epoch={epoch}/>
      <button onClick={() => {
        updateEpoch(epoch+60000)
      }}>ADD 1 min</button>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

I expect each click should update the input value with updated epoch prop value. But it wont happen. useState inside the Input won't fires.

Working demo

Updated

I cant use useEffect inside Input function it triggers multiple, multiple rerender, because im using redux-form.

Upvotes: 1

Views: 4614

Answers (1)

xadm
xadm

Reputation: 8418

const [value, updateValue] = useState(translateValueToString(epoch))

translateValueToString is used only once, to initialize state. Props change doesn't update value, epoch not used in rendering, no view update.

useEffect(() => {
  updateValue( translateValueToString(epoch) )
}, [epoch])

Upvotes: 2

Related Questions