Reactjs DetailsList正在重新渲染,因此将失去其状态
因此,我一直在尝试实现这样一个想法:每当用户单击Details列表中的任何一行时,按钮就会被启用,而当用户在selectionzone之外单击时,按钮就会被禁用 这是我的密码Reactjs DetailsList正在重新渲染,因此将失去其状态,reactjs,spfx,fluent-ui,fluentui-react,Reactjs,Spfx,Fluent Ui,Fluentui React,因此,我一直在尝试实现这样一个想法:每当用户单击Details列表中的任何一行时,按钮就会被启用,而当用户在selectionzone之外单击时,按钮就会被禁用 这是我的密码 import { DetailsList, SelectionMode, Selection, ISelection, initializeIcons, PrimaryButton } from '@fluentui/react' import {useMemo } from 'react' import { useBoo
import { DetailsList, SelectionMode, Selection, ISelection, initializeIcons, PrimaryButton } from '@fluentui/react'
import {useMemo } from 'react'
import { useBoolean } from '@uifabric/react-hooks'
interface ICurrency {
type: string,
amount: number
}
function App() {
initializeIcons()
const [isBtn, { setTrue: disableBtn, setFalse: enableBtn }] = useBoolean(true)
const items: ICurrency[] = [
{
type: 'INR',
amount: 20
},
{
type: 'USD',
amount: 50
},
{
type: 'GBP',
amount: 70
}
]
const selection: ISelection = useMemo(() => new Selection(
{
onSelectionChanged: ()=>{
if(selection.getSelectedCount() > 0){
enableBtn()
}else{
disableBtn()
}
}
}
), [items])
return (
<div className="App">
<PrimaryButton text="Button" disabled={isBtn}/>
<DetailsList
items={items} selectionMode={SelectionMode.single}
selection={selection}
/>
</div>
);
}
export default App;
从'@fluentui/react'导入{DetailsList,SelectionMode,Selection,ISelection,initializecons,PrimaryButton}
从“react”导入{useMemo}
从'@uifabric/react hooks'导入{useBoolean}
界面电流{
类型:字符串,
金额:数字
}
函数App(){
初始值()
const[isBtn,{setTrue:disableBtn,setFalse:enableBtn}]=useBoolean(true)
常数项:ICurrency[]=[
{
类型:“INR”,
金额:20
},
{
类型:'美元',
金额:50
},
{
类型:“GBP”,
金额:70
}
]
常量选择:ISelection=useMemo(()=>新选择(
{
onSelectionChanged:()=>{
if(selection.getSelectedCount()>0){
enableBtn()
}否则{
disableBtn()
}
}
}
),[项目])
返回(
);
}
导出默认应用程序;
我甚至使用useMemo并不断地敲打我的头,但问题仍然存在,单击任何一行,状态将丢失,并且按钮未启用。我已经尝试过存储选择状态了,count,除了它之外,我似乎遗漏了一些实现所必需或基本的东西您需要记忆
项
,因为在每次渲染时,它被重新分配并被视为一个新数组,这会导致您的选择
发生变化,因为它依赖项
作为使用记忆
依赖项。在每次状态更新时,选择将重置
因此,解决此问题的一种方法是将项移出函数,使其保留引用,而不是在每个渲染上创建新的项数组
const items = [
{
type: "INR",
amount: 20
},
{
type: "USD",
amount: 50
},
{
type: "GBP",
amount: 70
}
];
function App() {
// code
}
或者在这些项目上使用usemo
:
const items = useMemo(() => [
{
type: "INR",
amount: 20
},
{
type: "USD",
amount: 50
},
{
type: "GBP",
amount: 70
}
],[]);
另外,我看到您有一个错误,初始化图标
应该只调用一次。因此,这可能应该放在useffect
中:
useEffect(() => {
initializeIcons();
},[])
应该是这样的:
import {
DetailsList,
SelectionMode,
Selection,
ISelection,
initializeIcons,
PrimaryButton
} from "@fluentui/react";
import { useMemo, useEffect } from "react";
import { useBoolean } from "@uifabric/react-hooks";
const items = [
{
type: "INR",
amount: 20
},
{
type: "USD",
amount: 50
},
{
type: "GBP",
amount: 70
}
];
function App() {
useEffect(() => {
initializeIcons();
}, []);
const [isBtn, { setTrue: disableBtn, setFalse: enableBtn }] = useBoolean(
true
);
const selection = useMemo(
() =>
new Selection({
onSelectionChanged: () => {
if (selection.getSelectedCount() > 0) {
enableBtn();
} else {
disableBtn();
}
}
}),
[items]
);
return (
<div className="App">
<PrimaryButton text="Button" disabled={isBtn} />
<DetailsList
items={items}
selectionMode={SelectionMode.single}
selection={selection}
/>
</div>
);
}
export default App;
导入{
详细列表,
选择模式,
选择,
我的选择,
初始化,
主按钮
}来自“@fluentui/react”;
从“react”导入{useMemo,useEffect};
从“@uifabric/react hooks”导入{useBoolean}”;
常数项=[
{
类型:“INR”,
金额:20
},
{
类型:“美元”,
金额:50
},
{
类型:“英镑”,
金额:70
}
];
函数App(){
useffect(()=>{
初始化图标();
}, []);
const[isBtn,{setTrue:disableBtn,setFalse:enableBtn}]=useBoolean(
真的
);
const selection=usemo(
() =>
新选择({
onSelectionChanged:()=>{
if(selection.getSelectedCount()>0){
enableBtn();
}否则{
禁用btn();
}
}
}),
[项目]
);
返回(
);
}
导出默认应用程序;
您需要记忆项目
,因为在每次渲染时,它被重新分配并视为一个新数组,这会导致您的选择
发生更改,因为它依赖于项目
作为使用记忆
依赖项。在每次状态更新时,选择将重置
因此,解决此问题的一种方法是将项移出函数,使其保留引用,而不是在每个渲染上创建新的项数组
const items = [
{
type: "INR",
amount: 20
},
{
type: "USD",
amount: 50
},
{
type: "GBP",
amount: 70
}
];
function App() {
// code
}
或者在这些项目上使用usemo
:
const items = useMemo(() => [
{
type: "INR",
amount: 20
},
{
type: "USD",
amount: 50
},
{
type: "GBP",
amount: 70
}
],[]);
另外,我看到您有一个错误,初始化图标
应该只调用一次。因此,这可能应该放在useffect
中:
useEffect(() => {
initializeIcons();
},[])
应该是这样的:
import {
DetailsList,
SelectionMode,
Selection,
ISelection,
initializeIcons,
PrimaryButton
} from "@fluentui/react";
import { useMemo, useEffect } from "react";
import { useBoolean } from "@uifabric/react-hooks";
const items = [
{
type: "INR",
amount: 20
},
{
type: "USD",
amount: 50
},
{
type: "GBP",
amount: 70
}
];
function App() {
useEffect(() => {
initializeIcons();
}, []);
const [isBtn, { setTrue: disableBtn, setFalse: enableBtn }] = useBoolean(
true
);
const selection = useMemo(
() =>
new Selection({
onSelectionChanged: () => {
if (selection.getSelectedCount() > 0) {
enableBtn();
} else {
disableBtn();
}
}
}),
[items]
);
return (
<div className="App">
<PrimaryButton text="Button" disabled={isBtn} />
<DetailsList
items={items}
selectionMode={SelectionMode.single}
selection={selection}
/>
</div>
);
}
export default App;
导入{
详细列表,
选择模式,
选择,
我的选择,
初始化,
主按钮
}来自“@fluentui/react”;
从“react”导入{useMemo,useEffect};
从“@uifabric/react hooks”导入{useBoolean}”;
常数项=[
{
类型:“INR”,
金额:20
},
{
类型:“美元”,
金额:50
},
{
类型:“英镑”,
金额:70
}
];
函数App(){
useffect(()=>{
初始化图标();
}, []);
const[isBtn,{setTrue:disableBtn,setFalse:enableBtn}]=useBoolean(
真的
);
const selection=usemo(
() =>
新选择({
onSelectionChanged:()=>{
if(selection.getSelectedCount()>0){
enableBtn();
}否则{
禁用btn();
}
}
}),
[项目]
);
返回(
);
}
导出默认应用程序;
被接受的答案对这个问题有正确的解释。我也只是想发布我的解决方案。我只需要存储项目的状态
import { DetailsList, SelectionMode, Selection, initializeIcons, PrimaryButton } from '@fluentui/react'
import { useEffect, useState } from 'react'
import { useBoolean } from '@uifabric/react-hooks'
interface ICurrency {
type: string,
amount: number
}
function App() {
useEffect(() => {
initializeIcons();
}, []);
const [isBtn, { setTrue: disableBtn, setFalse: enableBtn }] = useBoolean(true)
let _selection = new Selection({
onSelectionChanged: () => {
if (_selection.getSelectedCount() > 0) {
enableBtn()
} else {
disableBtn()
}
}
});
let _initialItems: ICurrency[] = [
{
type: 'INR',
amount: 20
},
{
type: 'USD',
amount: 50
},
{
type: 'GBP',
amount: 70
}
]
const [items, setItems] = useState(_initialItems)
return (
<>
<PrimaryButton text="Button" disabled={isBtn} />
<DetailsList
items={items}
selection={_selection}
selectionMode={SelectionMode.single}
/>
</>
);
}
export default App;
从'@fluentui/react'导入{DetailsList,SelectionMode,Selection,initializecons,PrimaryButton}
从“react”导入{useEffect,useState}
从'@uifabric/react hooks'导入{useBoolean}
界面电流{
类型:字符串,
金额:数字
}
函数App(){
useffect(()=>{
初始化图标();
}, []);
const[isBtn,{setTrue:disableBtn,setFalse:enableBtn}]=useBoolean(true)
让_选择=新选择({
onSelectionChanged:()=>{
如果(_selection.getSelectedCount()>0){
enableBtn()
}否则{
disableBtn()
}
}
});
让_initialItems:iccurrency[]=[
{
类型:“INR”,
金额:20
},
{
类型:'美元',
金额:50
},
{
类型:“GBP”,
金额:70
}
]
const[items,setItems]=useState(_initialItems)
返回(
);
}
导出默认应用程序;
现在假设项目来自某些道具或某些状态管理,那么只需在useEffect中使用setItems,并将依赖项设置为该源