[英]How to change the value of a prop of Sub Component passed as a column to React Table?
I am using React Table Library in Web Application.我在 Web 应用程序中使用React 表库。
I am passing a component as a column to the table.我将一个组件作为列传递给表。 Columns and data for the table looks like below.
表格的列和数据如下所示。
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)}
/>
)
}
];
My TestComponent
Looks like below.我的
TestComponent
如下所示。
const TestComponent = ({ id, inProgress, onClickHandler }) => {
return (
<div>
{inProgress ? (
<p>In Progress </p>
) : (
<button onClick={() => onClickHandler(id)}>click me</button>
)}
</div>
);
};
What my purpose is, When user click on click me
button it needs to call a Backend API
.我的目的是,当用户单击
click me
按钮时,它需要调用Backend API
。 At that time inProgress
prop need to be true
and it should pass to the table and need text as In Progress until API call completed.那时
inProgress
道具需要为true
,它应该传递到表格并需要文本作为正在进行中,直到 API 调用完成。
I could be able to do it changing state
as below.我可以改变
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);
}
I could be able to achieve what I need But I am not satisfied the way I am changing the state
.我可以实现我所需要的但我对更改
state
的方式不满意。 I need to know is there a better way of doing this without changing state
like this.我需要知道是否有更好的方法来做到这一点,而无需像这样更改
state
。
You can use this StackBlitz Link for giving me a better solution.您可以使用此StackBlitz Link 为我提供更好的解决方案。 Thanks.
谢谢。
Instead of passing inProgress
prop to TestComponent
, you could maintain a local state in the TestComponent
that is used to determine whether to show progress text or a button and only pass the id
and onClickHanlder
props to TestComponent
.您可以在
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. 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. This callback function will be called when API request is completed.当 API 请求完成时,将调用此回调 function。 This callback function is defined inside
TestComponent
and only toggles the local state of the TestComponent
to hide the progress text and show the button again.此回调 function 在
TestComponent
内部定义,仅切换TestComponent
的本地 state 以隐藏进度文本并再次显示按钮。
Change your TestComponent
to as shown below:将您的
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>
);
};
i have used useState
hook to maintain local state of the TestComponent
as it is a functional component but you could use the same logic in a class component as well.我使用
useState
挂钩来维护TestComponent
的本地 state,因为它是一个功能组件,但您也可以在 class 组件中使用相同的逻辑。
Change the TestComponent
in sampleData
array to only be passed two props, id
and onClickHandler
.将
sampleData
数组中的TestComponent
更改为仅传递两个道具, id
和onClickHandler
。
{
id: 1,
name: "Product one",
action: <TestComponent id={1} onClickHandler={this.onClickHandler} />
}
and change onClickHandler
method in App
component to:并将
App
组件中的onClickHandler
方法更改为:
onClickHandler(id, callback) {
// make the api request, call 'callback' function when request is completed
setTimeout(() => {
callback();
}, 3000);
}
Alternatively, you could make onClickHandler
function in App
component to return a Promise
that is fulfilled when API request completes.或者,您可以在
App
组件中创建onClickHandler
function 以返回Promise
,该 API 请求完成时已完成。 This way you don't have to pass a callback function from TestComponent
to onClickHandler
method in App
component.这样您就不必将回调 function 从
TestComponent
传递给App
组件中的onClickHandler
方法。
Change onClickHandler
method to: onClickHandler
方法更改为:
onClickHandler(id) {
return new Promise((resolve, reject) => {
setTimeout(resolve, 3000);
});
}
and change TestComponent
to:并将
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.