Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在函数组件中仅重新呈现JSX?_Javascript_Reactjs_React Hooks_Components - Fatal编程技术网

Javascript 如何在函数组件中仅重新呈现JSX?

Javascript 如何在函数组件中仅重新呈现JSX?,javascript,reactjs,react-hooks,components,Javascript,Reactjs,React Hooks,Components,我正在学习通过制作战舰游戏来做出反应。我的网格如下所示: const [board, setBoard] = useState([{ship: false, beenHit: false}, {ship: true, beenHit: false}, {ship: true, beenHit: false},{ship: false, beenHit: false}, {ship: false, beenHit: false},

我正在学习通过制作战舰游戏来做出反应。我的网格如下所示:

const [board, setBoard] = 
   useState([{ship: false, beenHit: false}, {ship: true, beenHit: false},
               {ship: true, beenHit: false},{ship: false, beenHit: false},
               {ship: false, beenHit: false},{ship: true, beenHit: false}
              ])
每个字段都是一个对象,有两个属性,这意味着该字段上是否有船,以及玩家是否已经单击了船。我为每个字段分配了receiveHit()函数,因此当玩家单击该字段时,它会将数组中的对象标记为{ship:true,beenHit:true}。它工作正常,但问题是,栅格不会重新渲染自身,因此场的颜色不会改变

用于决定类名(从而决定字段颜色)的函数:

重新运行的JSX:

return ({
 board.map((field, i)=> <div onClick = {() => board.receiveHit(i)} className = {decideColor(field)}> 
 </div> )
})
返回({
board.map((field,i)=>board.receiveHit(i)}className={decideColor(field)}>
)
})

它在一个功能组件内。我无法重新渲染整个组件,因为船的位置将发生变化(它们随机放置在板上)

我假设您直接在状态中设置字段。这样,board对象保持不变,不会触发重新渲染。您必须重新分配状态,从而为react创建一个状态更改,以便对其进行响应。问题是:您没有重新渲染整个组件。您的函数正在返回新状态,是的。但是React的内部机制决定了哪些需要重新呈现给DOM,哪些不需要(道具和键在这里起作用,请确保使用它们)。以我的示例为例,打开DevTools并观察单击框时所做的更改。您将只看到单击的div被呈现到DOM中。因此,明智的做法是制作大量较小的组件,以提高重新渲染的效率

.board{
显示器:flex;
宽度:计算(20em+20px);/*10x10带边框的字段*/
柔性包装:包装;
}
.字段{
显示:内联块;
宽度:2米;
高度:2米;
背景颜色:浅灰色;
边框:薄而实的黑色;
}
.野战舰{
背景颜色:蓝色;
}
打{
背景颜色:灰色;
}
.场上,船上,命中{
背景色:红色;
}

常量字段=({Field,…props})=>{
返回
}
委员会=()=>{
//初始10 x 10板
const[board,setBoard]=React.useState([…新数组(100)].map((元素,索引)=>{return{}]);
const onClick=(事件,i)=>{
//这将采用现有板,用索引i替换元素
//将hit设置为true。并将新创建的*copy*设置为新
//板的版本。它将触发重新渲染,但如上所述
//以前,只有真正更改过的(在本例中是更改了类名)才会
//渲染到DOM。
setBoard(对象分配([…板]{
[i] :{
…董事会[i],
hit:对
}
}));
}  
常量decideClassName=(i)=>{
//颜色基于关键点和生成的类组合,
//野战、野战飞船、野战飞船命中和野战命中(参见CSS)
返回`field${Object.keys(board[i]).join(“”)}`;
}
常数设置芯片=(电路板,x,y,长度,类型=“水平”)=>{
常数指数=y*10+x;
for(设i=0;i{
常量副本=[…板];
固定芯片(副本,5,5,4);
固定片(副本,2,2,3,“垂直”);
立板条(复印件);
}, [])
返回(
{
map((field,i)=>onClick(event,i)}className={decideClassName(i)}/>)
}
)
}
ReactDOM.render(
,
document.getElementById('root'))
);
return ({
 board.map((field, i)=> <div onClick = {() => board.receiveHit(i)} className = {decideColor(field)}> 
 </div> )
})