I have a chart and an input field below. Basically the user can ask a question and the chart will change accordingly. Here is how it looks like
Here is the sample of the code below (ignore CoreUI syntaxes)
<CRow>
<CCol xs="12" sm="12" lg="12">
<CCard id="answerScreen" style={{height: "500px"}}>
{
!tempResponse.loading? tempResponse.data.map(value => (
<ChartRender
key={uuidv4()}
data={value}
/>
))
:
<Loader/>
}
</CCard>
</CCol>
</CRow>
<CRow>
<CCol xs="12" sm="12" lg="12">
<CCard>
<CCardBody>
<CForm className="form-horizontal">
<CFormGroup>
<CInputGroup size="lg" className="input-prepend">
<CInputGroupPrepend>
<CInputGroupText className="">@Ask</CInputGroupText>
</CInputGroupPrepend>
<CInput
size="16"
type="text"
value={userInput || ""}
onChange={e=> handleTextBoxInput(e)}
onClick={e=> handleTextBoxClick(e)}
onKeyPress={e => handleTextBoxEnter(e)}
id="userQuery"
/>
<CInputGroupAppend>
<CButton color="primary">Send</CButton>
</CInputGroupAppend>
</CInputGroup>
</CFormGroup>
</CForm>
</CCardBody>
</CCard>
</CCol>
</CRow>
This is how I have defined my states
const [userInput, setUserInput] = React.useState("");
const [tempResponse, setTempResponse] = React.useState({
data: []
})
I suspect the problem in this part of the code
<CInput
size="16"
type="text"
value={userInput || ""}
onChange={e=> handleTextBoxInput(e)}
onClick={e=> handleTextBoxClick(e)}
onKeyPress={e => handleTextBoxEnter(e)}
id="userQuery"
/>
I even tried adding useCallback
to onChange
function like this
const handleTextBoxInput = useCallback(e =>{
e.preventDefault();
setUserInput(e.target.value)
}, [])
But no help. I even read about memo
but not sure where or how to apply it in my situation. What am I doing wrong?
OBSERVATION
As mentioned by @Matthew
,arrow syntax creates a different callback each time which contributes to re rendering and hence must be removed.
But even after removing it, the chart is getting re rendered every time a key is pressed. I am using Chartjs
which uses canvas
internally. Is Chartjs
a problem?
On your input, you have two events firing on every keypress -
onKeyPress
andonChange
- remove theonKeyPress
.I suspect that
handleTextBoxEnter
callssetTempResponse
which updates tempResponse. Setting state that the UI depends on will trigger a re-render.You should also handle form submissions using the onSubmit event. If an element has focus inside of a form and the enter button is pressed - it will fire onSubmit.
Also, if a key changes React will re-render. You are calling a function in your key so it is updated on every update.
FYI manually creating a UUID for a key overkill.