[英]How to change the value of a prop of Sub Component passed as a column to React Table?
我在 Web 应用程序中使用React 表库。
我将一个组件作为列传递给表。 表格的列和数据如下所示。
columns = [
{
Header: "Name",
accessor: "name"
},
{
Header: "Action",
accessor: "action"
}
];
sampleData = [
{
id: 1,
name: "Product one",
action: (
<TestComponent
id={1}
inProgress={false}
onClickHandler={id => this.onClickHandler(id)}
/>
)
},
{
id: 2,
name: "Product two",
action: (
<TestComponent
id={2}
inProgress={false}
onClickHandler={id => this.onClickHandler(id)}
/>
)
}
];
我的TestComponent
如下所示。
const TestComponent = ({ id, inProgress, onClickHandler }) => {
return (
<div>
{inProgress ? (
<p>In Progress </p>
) : (
<button onClick={() => onClickHandler(id)}>click me</button>
)}
</div>
);
};
我的目的是,当用户单击click me
按钮时,它需要调用Backend API
。 那时inProgress
道具需要为true
,它应该传递到表格并需要文本作为正在进行中,直到 API 调用完成。
我可以改变state
如下。
onClickHandler(id) {
const newData = this.sampleData.map(data => {
if (data.id === id) {
return {
...data,
action: (
<TestComponent
id={1}
inProgress={true}
onClickHandler={id => this.onClickHandler(id)}
/>
)
};
}
return data;
});
this.setState({ data: newData });
// Here I Call the Backend API and after complete that need to show the click me button again.
setTimeout(() => {
this.setState({ data: this.sampleData });
}, 3000);
}
我可以实现我所需要的但我对更改state
的方式不满意。 我需要知道是否有更好的方法来做到这一点,而无需像这样更改state
。
您可以使用此StackBlitz Link 为我提供更好的解决方案。 谢谢。
您可以在TestComponent
中维护一个本地 state ,而不是将inProgress
道具传递给TestComponent
,用于确定是显示进度文本还是按钮,并且只将id
和onClickHanlder
道具传递给TestComponent
。
When button is clicked in TestComponent
, you could set the the local state of TestComponent
to show the progress text and then call the onClickHandler
function passed as prop, passing in the id
prop and a callback function as arguments. 当 API 请求完成时,将调用此回调 function。 此回调 function 在TestComponent
内部定义,仅切换TestComponent
的本地 state 以隐藏进度文本并再次显示按钮。
将您的TestComponent
更改为如下所示:
const TestComponent = ({ id, onClickHandler }) => {
const [showProgress, setShowProgress] = React.useState(false);
const toggleShowProgress = () => {
setShowProgress(showProgress => !showProgress);
};
const handleClick = () => {
setShowProgress(true);
onClickHandler(id, toggleShowProgress);
};
return (
<div>
{showProgress ? (
<p>In Progress </p>
) : (
<button onClick={handleClick}>click me</button>
)}
</div>
);
};
我使用useState
挂钩来维护TestComponent
的本地 state,因为它是一个功能组件,但您也可以在 class 组件中使用相同的逻辑。
将sampleData
数组中的TestComponent
更改为仅传递两个道具, id
和onClickHandler
。
{
id: 1,
name: "Product one",
action: <TestComponent id={1} onClickHandler={this.onClickHandler} />
}
并将App
组件中的onClickHandler
方法更改为:
onClickHandler(id, callback) {
// make the api request, call 'callback' function when request is completed
setTimeout(() => {
callback();
}, 3000);
}
或者,您可以在App
组件中创建onClickHandler
function 以返回Promise
,该 API 请求完成时已完成。 这样您就不必将回调 function 从TestComponent
传递给App
组件中的onClickHandler
方法。
onClickHandler
方法更改为:
onClickHandler(id) {
return new Promise((resolve, reject) => {
setTimeout(resolve, 3000);
});
}
并将TestComponent
更改为:
const TestComponent = ({ id, onClickHandler }) => {
const [showProgress, setShowProgress] = useState(false);
const toggleShowProgress = () => {
setShowProgress(showProgress => !showProgress);
};
const handleClick = () => {
setShowProgress(true);
onClickHandler(id)
.then(toggleShowProgress)
.catch(error => {
toggleShowProgress();
// handle the error
});
};
return (
<div>
{showProgress ? (
<p>In Progress </p>
) : (
<button onClick={handleClick}>click me</button>
)}
</div>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.