[英]Parent React component not re-rendering on change state in child using react hooks;
[英]React hooks: Parent component not re-rendering
我正在尝试使用回调从子级更新父组件的 state。 state 和回调被传递到文本输入。 正在调用回调,父级的 state 已更改,但不会重新渲染。 输入字段的值保持不变。 如果使用强制渲染,则每次添加新字符时文本字段都会更新(根据需要)。 我不确定是什么原因造成的,据我了解,除非 state 未更改,否则提供的 setState 挂钩应该会重新呈现。
编辑:(添加了父组件而不仅仅是回调)下面是父组件
import Card from './Card'
import Instructions from './instructions'
import Title from './title'
import React, { useRef, useState, useCallback, useEffect } from 'react'
import { DropTarget } from 'react-dnd'
import ItemTypes from './ItemTypes'
import update from 'immutability-helper'
const Container = ({ connectDropTarget }) => {
const ref = useRef(null)
const titleRef = useRef()
const instructionsRef = useRef()
const appRef = useRef()
useEffect(() => {
// add when mounted
document.addEventListener("mousedown", handleClick);
// return function to be called when unmounted
return () => { document.removeEventListener("mousedown", handleClick);};
}, []);
const handleClick = e => {
if (titleRef.current.contains(e.target)) {
setFocus("Title");
return;
} // outside click
else if(instructionsRef.current.contains(e.target)){
setFocus("Instructions");
return;
}
setFocus(null);
};
const [, updateState] = useState();
const forceUpdate = useCallback(() => updateState({}), []);
const [focus,setFocus] = useState(null);
const [title, setTitle] = useState({id: "Title", text: "Default",type: "Title", data:[]});
const [instructions, setInstructions] = useState({id: "Instructions",type:"Instructions", text: "Instructions", data:[]});
const [cards, setCards] = useState([
{
id: 1,
text: 'Write a cool JS library',
},
{
id: 2,
text: 'Make it generic enough',
},
{
id: 3,
text: 'Write README',
},
{
id: 4,
text: 'Create some examples',
},
{
id: 5,
text: 'Spam in Twitter and IRC to promote it',
},
{
id: 6,
text: '???',
},
{
id: 7,
text: 'PROFIT',
},
])
const moveCard = useCallback(
(id, atIndex) => {
const { card, index } = findCard(id)
setCards(
update(cards, {
$splice: [[index, 1], [atIndex, 0, card]],
}),
)
},
[cards],
)
const findCard = useCallback(
id => {
const card = cards.filter(c => `${c.id}` === id)[0]
return {
card,
index: cards.indexOf(card),
}
},
[cards],
)
const updateItem = useCallback(
(id,field,additionalData,value) => {
return;
},
[cards], //WHat does this do?
)
const updateTitle = text => {
console.log("Updating title")
let tempTitle = title;
tempTitle['text'] = text;
//console.log(text);
//console.log(title);
//console.log(tempTitle);
setTitle(tempTitle);
//console.log(title);
//console.log("done");
forceUpdate(null);
}
connectDropTarget(ref)
return (
<div ref={appRef}>
<div ref={titleRef} >
<Title item={title} focus={focus} updateFunction={updateTitle}/>
</div>
<div ref={instructionsRef} >
<Instructions item={instructions} focus={focus}/>
</div>
<div className="Card-list" ref={ref}>
{cards.map(card => (
<Card
key={card.id}
id={`${card.id}`}
text={card.text}
moveCard={moveCard}
findCard={findCard}
item={card}
focus={focus}
/>
))}
</div>
</div>
)
}
export default DropTarget(ItemTypes.CARD, {}, connect => ({
connectDropTarget: connect.dropTarget(),
}))(Container)
调用此 function 的组件代码为:
import React from 'react'
function Title(props) {
if(props.focus === "Title")
return(
<input
id="Title"
class="Title"
type="text"
value={props.item['text']}
onChange = { e => props.updateFunction(e.target.value)}
/>
);
else
return (
<h1> {props.item['text']} </h1>
);
}
export default Title
问题就在这里
const updateTitle = text => {
let tempTitle = title; // These two variables are the same object
tempTitle['text'] = text;
setTitle(tempTitle); // problem is here
}
React 使用 object.is() 方法来比较前后两个值。 看这个
Object.is(title, tempTitle) // true
你应该让“title”和“tempTitle”不同的对象,像这样
const updateTitle = text => {
let tempTitle = {...title}; // tempTitle is a new object
tempTitle['text'] = text;
setTitle(tempTitle);
}
这是可变 object 的演示。
var a= {name:1} var b = a; b.name=2 var result = Object.is(a,b) console.log(result) // true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.