Javascript 受控Fluent UI复选框组件的呈现不正确

Javascript 受控Fluent UI复选框组件的呈现不正确,javascript,reactjs,checkbox,office-ui-fabric,fluentui-react,Javascript,Reactjs,Checkbox,Office Ui Fabric,Fluentui React,我有一个表单,它通过RESTAPI与数据库交互,并显示几个受控的Fluent UI组件。对于多选字段,我构建了一个组件,它显示一个包含任意数量受控复选框组件的堆栈。下面是组件定义 class MultiChoiceField扩展了React.Component { 静态contextType=FormContext; 静态显示名称=“MultiChoiceField”; #处理程序={change:{}}; /** *使用{@link FormContext}提供的{@link Item}中提供

我有一个表单,它通过RESTAPI与数据库交互,并显示几个受控的Fluent UI组件。对于多选字段,我构建了一个组件,它显示一个包含任意数量受控复选框组件的堆栈。下面是组件定义

class MultiChoiceField扩展了React.Component
{
静态contextType=FormContext;
静态显示名称=“MultiChoiceField”;
#处理程序={change:{}};
/**
*使用{@link FormContext}提供的{@link Item}中提供的信息初始化组件。
*@constructor
*@param{Object}支持为此组件提供的属性。
*/
建造师(道具)
{
超级(道具);
this.state={value:{}};
}
/**
*一旦组件添加到DOM中,就设置它。上下文在构造函数中不可用,所以我们设置
*这里有价值。
*@函数
*@param{Object}nextProps将分配给'this.props'的值。
*@param{Object}nextContext将分配给` this.context`的{@link FormContext}。
*@公众
*@returns{void}
*/
componentDidMount(nextProps,nextContext)
{
const choices=nextrops?.Field?.choices?.results | |[];
让value=nextContext?.Item?[nextProps.FieldName]| |{};
value=Array.isArray(value)?value:(value.results | |[]);
这是我的国家({
value:choices.reduce((结果,选择)=>({…结果,[choice]:value.indexOf(选择)>=0}),{})
});
}
/**
*当组件收到新道具或上下文信息时更新组件。
*@函数
*@param{Object}nextProps将分配给'this.props'的值。
*@param{Object}nextContext将分配给` this.context`的{@link FormContext}。
*@公众
*@returns{void}
*/
组件将接收道具(nextProps、nextContext)
{
const choices=nextrops?.Field?.choices?.results;
让value=nextContext.Item?[nextProps.FieldName]| |{};
value=Array.isArray(value)?value:(value.results | |[]);
这是我的国家({
value:choices.reduce((结果,选择)=>({…结果,[choice]:value.indexOf(选择)>=0}),{})
});
}
/**
*获取指定选项的事件处理程序。
*@函数
*@param{string}命名与此事件处理程序关联的选项。
*@公众
*@返回指定选项的{function}事件处理程序。
*/
handleChange=(名称)=>
{
const bubbleOnChange=(事件、值)=>
(this.props.onChange?(事件、对象、键(值)、过滤器((选项)=>(值[choice]));
如果(!this.#handlers.change[name])
{
此.#handlers.change[name]=(事件)=>
{
常量值={…this.state.value[name]:!this.state.value[name]};
this.setState({value},()=>(void bubbleOnChange(事件,值)));
};
}
返回此项。#处理程序。更改[名称];
}
/**
*将此组件的用户界面呈现为
*[Stack]{@linkhttps://developer.microsoft.com/en-us/fluentui#/controls/web/stack}包含
*[复选框]{@linkhttps://developer.microsoft.com/en-us/fluentui#/controls/web/checkbox}组成部分。
*@函数
*@公众
*@返回{JSX}此组件的用户界面。
*/
render()
{
const choices=this.props.Field.choices.results;
返回(
{choices.map((choice)=>(
))}
{this.props.errorMessage}
);
}
}
表单通过RESTAPI检索数据后,该组件使用该数据更新其状态。虽然状态已正确更新,并且每个复选框组件的正确值都被传递到
props
,但UI会产生误导。例如,根据Chrome DevTools中的React Components inspector,下面选中的
值分别设置为
false
true
false
false

显然,虽然正确设置了
道具
,但用户会看到五个未勾选的复选框。当用户单击本应勾选的复选框时,
状态将正确更新,以反映所有五个复选框均未勾选。这是用户单击第二个复选框后的外观


用户与复选框组件交互,它们的行为符合预期,但对于初始
checked
属性设置为
true
的任何位置,基础值都会完全反转,我向构造函数添加了
上下文
,但这没有帮助,所以我把这个类组件转换成了一个功能组件。它按预期工作。下面是功能组件的代码

constmultichoicefield=({errorMessage=”“,Field,FieldName,onChange,stackTokens={}}={})=>
{
const context=useContext(FormContext);
const[value,setValue]=useState({});
const handleChange=(选择)=>(事件)=>
{
const bubbleOnChange=(事件,值)=>(void onChange?(事件,值));
常量getValueAsArray=(valueNew)=>
(Object.entries(valueNew).filter(([,value])=>(value)).map(([key])=>(key));
const valueNew={…value[choice]:!value[choice]};
bubbleOnChange(事件,getValueAsArray(valueNew));
};
const updatechices=()=>
{
const reduceSelected=(valueContext)=>(结果,选择)=>
({……结果,[choice]:~valueContext.indexOf(choice)});
常量选项=字段?.choices?.results | |[];
让valueContext=context?.Item?[FieldName]| |{};
valueContext=Array.isArray(valueContext)?valueContext:(valueContext.results | |[]);
setValue(choices.reduce(reduceSelected(valueContext),{});
};
useEffect(UpdateChiices,[Field?.Choices,FieldName,context?.Item]);
const renderChoice=(选项)=>(
);
返回(