useState 在函数和组件 React 中的行为不同
useState behaves differently in function vs componenet React
import React, {useState} from 'react'
import './box.css'
import cross from './cross.png';
import axios from 'axios'
function Box(props){
const[disappear, setdisappear] = useState(false)
const[appear, setappear] = useState(false)
const[text, settext] = useState('')
const[able, setable] = useState(true)
async function clear(){
console.log(props.id)
setdisappear(true)
let id = props.id
let token = sessionStorage.getItem('token')
let data = {token:token, id:id}
await axios.post('http://localhost:5000/home/deleteText', data)
}
function theText(e){
let current = e.target.value
console.log(current)
settext(current)
console.log(text)
if(current===''){
setable(true)
}else{
setable(false)
}
}
async function savetext(){
let data = {text:text, token:sessionStorage.getItem('token')}
const request = await axios.post('http://localhost:5000/home/addText',data)
//e.target.reset()
document.getElementById('textarea').value = ''
setable(true)
setappear(true)
}
function boxx(){
return(
<div className = 'wrapper'>
<div className='outerbox'>
<div className='empty'>
</div>
<textarea id = 'textarea' onChange ={theText} className='input' rows="10" cols="50" placeholder='enter ur text mf' defaultValue={props.text}></textarea>
<div className='x'>
<button onClick={clear} value={props.id} disabled = {props.disableButton}>
{props.disableButton?'':<img src={cross} alt = '' />}
</button>
</div>
{props.disableButton?<div><button disabled = {able} onClick = {savetext}>save</button></div>:''}
</div>
</div>
)
}
return(
<div>
{disappear?null:boxx()}
{appear?boxx():null}
</div>
)
}
export default Box
因此,正如您在组件 Box 的 return 语句中看到的那样,我调用了 boxx 函数,该函数 return 是盒子的 html。在这种情况下,如果我在文本区域输入一些文本,文本会按预期打印,但是如果我将 boxx 函数更改为 Boxx 并且在 return 语句中我将其用作 <Boxx/>
,我在 textarea 中输入的文本被立即删除,或者只打印一个字母,在我输入第二个字母后,它们都被删除。我想通了,这种奇怪的行为是因为 theText 函数中的 useState 但不知道为什么会这样。我该如何解决?
因为 Boxx
是在 Box
内部定义的,所以它的组件类型在每次 Box
重新渲染时都会改变,这会导致 React 的 diffing algorithm 重置<textarea>
里面。
import React, {useState} from 'react'
import './box.css'
import cross from './cross.png';
import axios from 'axios'
function Box(props){
const[disappear, setdisappear] = useState(false)
const[appear, setappear] = useState(false)
const[text, settext] = useState('')
const[able, setable] = useState(true)
async function clear(){
console.log(props.id)
setdisappear(true)
let id = props.id
let token = sessionStorage.getItem('token')
let data = {token:token, id:id}
await axios.post('http://localhost:5000/home/deleteText', data)
}
function theText(e){
let current = e.target.value
console.log(current)
settext(current)
console.log(text)
if(current===''){
setable(true)
}else{
setable(false)
}
}
async function savetext(){
let data = {text:text, token:sessionStorage.getItem('token')}
const request = await axios.post('http://localhost:5000/home/addText',data)
//e.target.reset()
document.getElementById('textarea').value = ''
setable(true)
setappear(true)
}
function boxx(){
return(
<div className = 'wrapper'>
<div className='outerbox'>
<div className='empty'>
</div>
<textarea id = 'textarea' onChange ={theText} className='input' rows="10" cols="50" placeholder='enter ur text mf' defaultValue={props.text}></textarea>
<div className='x'>
<button onClick={clear} value={props.id} disabled = {props.disableButton}>
{props.disableButton?'':<img src={cross} alt = '' />}
</button>
</div>
{props.disableButton?<div><button disabled = {able} onClick = {savetext}>save</button></div>:''}
</div>
</div>
)
}
return(
<div>
{disappear?null:boxx()}
{appear?boxx():null}
</div>
)
}
export default Box
因此,正如您在组件 Box 的 return 语句中看到的那样,我调用了 boxx 函数,该函数 return 是盒子的 html。在这种情况下,如果我在文本区域输入一些文本,文本会按预期打印,但是如果我将 boxx 函数更改为 Boxx 并且在 return 语句中我将其用作 <Boxx/>
,我在 textarea 中输入的文本被立即删除,或者只打印一个字母,在我输入第二个字母后,它们都被删除。我想通了,这种奇怪的行为是因为 theText 函数中的 useState 但不知道为什么会这样。我该如何解决?
因为 Boxx
是在 Box
内部定义的,所以它的组件类型在每次 Box
重新渲染时都会改变,这会导致 React 的 diffing algorithm 重置<textarea>
里面。