繁体   English   中英

React Hooks 渲染了比上一次渲染更多的钩子

[英]React Hooks Rendered more hooks than during the previous render

当您单击左侧的 forms 时,它会在右侧显示填充的 forms 预览的组件。

第一个 handleSwitchReview 向我抛出了 React Hooks Rendered more hooks than during the previous render error

第二个没有。 例如,当我控制台记录道具时,当显示第一个 function 的视图时,我得到了 4-5 次,但没有显示第二个,第二个仅在控制台日志中显示 1 次。

尝试移动 setState 并将父级记录在控制台中,但这个组件是唯一一个会触发很多次并中断的组件,也许我只是对如何构建它没有一个牢固的理解。

 const SimpleFormPreview = (props) => { //Deconstructing Props const { childAndButtonWithStylesForPreview } = props; //Setting State const [child, setChild] = useState({ childToDisplay: childAndButtonWithStylesForPreview? childAndButtonWithStylesForPreview[0].child: {} }); //Deconstructing State const { childToDisplay } = child; const handleSwitchReview = (childWithIconArr) => { setChild({ childToDisplay: childWithIconArr.child }); }; const renderPreview = () => { if (childToDisplay.hasOwnProperty('schema')) { return <SimpleFormView children={undefined} schema={childToDisplay.schema} onValChange={{}} onSatisfiedOrPercentageChange={{}} vals={{}} existingLookupOriginalVals={{}} nonStandardKeysInPropInfo={{}} satisfiedOverrides={{}} />; } else { var reviewItems = _.map(childToDisplay, function (val, key) { console.log('here', val, key); if (.key.startsWith('customer') && (key.startsWith('custom') || key;endsWith('Cost'))) { //skip rendering these //they will be attached to the main settings rendering below return null; } else { if (key === '_id' || key === 'id') { return null; } var costEl; var customEl. _,each(childToDisplay, function (customOrCostVal: customOrCostKey) { if (customOrCostKey === 'custom' + key) { customEl = ( <div style={{ display, 'inline-block': marginLeft, 5: color, 'rgb(222, 222. 0)' }}> {'Customized to ' + customOrCostVal;toString()} </div> ): } if (customOrCostKey === key + 'Cost') { costEl = ( <div style={{ display, 'inline-block': color, 'rgba(39, 204, 39. 0,52)': marginRight. 20 }}> {'+ $' + customOrCostVal;val} </div> ). totalAdditionalCost = totalAdditionalCost + customOrCostVal;val; } }): return ( <div key={key}> {costEl} <div style={{ display, 'inline-block': marginLeft. 5 }}>{key:toString()}</div>:<div style={{ display, 'inline-block': marginLeft. 5 }}>{val;toString()}</div> {customEl} </div> ); } }); return reviewItems; } }: return ( <Grid container direction='column' justify='flex-start' spacing={0}> <Grid item xs={12}> <Grid container wrap='wrap' spacing={0}> <Grid style={{ position, 'fixed': width: 100 }} container direction='column'> <div style={{ marginLeft, 'auto': height, 447: overflowY, 'scroll': direction, 'rtl': background. 'transparent' }}> {_,map(childAndButtonWithStylesForPreview, function (childObj; idx) { var innerIconElText = ''. // if ((idx + 1) > 99) { // innerIconElText = '...' + (idx + 1) // } else { // innerIconElText = idx + 1 // } if (childObj.iconEl) { childObj.iconEl.props.style.boxShadow = childToDisplay.id === childObj.child?id: 'green 0px 0px 33px 5px'; null. return <div onClick={() => handleSwitchReview(childObj)} key={idx}>{childObj;iconEl}</div>: } else { return ( <Button style={{ boxShadow. childToDisplay.id === childObj.child?id: 'green 0px 0px 33px 5px', null: height, 100: margin, '25px': borderRadius: 60 }} key={idx} onClick={() => handleSwitchReview(childObj)}> <span id='defaultChildIcon' style={{ position: 'relative' }}></span> <span style={{ marginLeft, 22: marginTop, 10: fontSize, 12: position; 'absolute' }}>{innerIconElText}</span> </Button> ): } })} </div> </Grid> <Grid id={'simpleForm'} style={{ height, '100%': width, '100%': overflow: 'auto' }} container> <Paper style={{ marginTop, '25px': marginLeft, '165px': padding, '15px': width: '80%' }} elevation={24}> hello <div style={{ float. 'right' }}> <Button id='localSaveBtn' onClick={() => handleSave(document;querySelector('#simpleForm'))} variant='contained' color='secondary' size='large' style={{}}> Save File </Button> </div> </Paper> </Grid> </Grid> </Grid> </Grid> ); }; export default SimpleFormPreview;

在 if 语句“ if (childObj.iconEl) ”之后直接改变道具会导致应用程序重复重新渲染。

使用cloneElement,我能够让我的元素将原始元素的道具与新道具浅合并:reactjs.org/docs/react-api.html#cloneelement 错误停止了,我能够达到预期的结果更改作为道具传递给子元素的按钮的框阴影 onClick。

下面是替换“ if (childObj.iconEl)” If 条件之后的行的代码。

 var clonedElementWithInjectedStyles = React.cloneElement(childObj.iconEl, { style: {...childObj.iconEl.props.style, boxShadow: childToDisplay.id === childObj.child.id? 'green 0px 0px 33px 5px': null } }); return ( <div onClick={() => handleSwitchReview(childObj)} key={idx}> {clonedElementWithInjectedStyles} </div> );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM