Вместо того, чтобы передавать inProgress
prop в TestComponent
, вы могли бы поддерживать локальное состояние в TestComponent
, которое используется для определения, показывать ли текст прогресса или кнопку, и передавать только id
и onClickHanlder
props в TestComponent
.
Когда кнопка нажата в TestComponent
, вы можете установить локальное состояние TestComponent
для отображения текста прогресса, а затем вызвать функцию onClickHandler
, переданную как prop, передав в опоре id
и функции обратного вызова в качестве аргументов. Эта функция обратного вызова будет вызываться после завершения запроса API. Эта функция обратного вызова определена внутри TestComponent
и только переключает локальное состояние TestComponent
, чтобы скрыть текст о ходе выполнения и снова показать кнопку.
Измените 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
, поскольку это функциональный компонент, но вы также можете использовать тот же logi c в компоненте класса.
Измените массив TestComponent
в sampleData
так, чтобы он передавал только два свойства: id
и onClickHandler
.
{
id: 1,
name: "Product one",
action: <TestComponent id={1} onClickHandler={this.onClickHandler} />
}
и измените метод onClickHandler
в компоненте App
на:
onClickHandler(id, callback) {
// make the api request, call 'callback' function when request is completed
setTimeout(() => {
callback();
}, 3000);
}
Демо
![Edit crazy-fire-fvlhm](https://codesandbox.io/static/img/play-codesandbox.svg)
Alternatively, you could make onClickHandler
function in App
component to return a Promise
that is fulfilled when API request completes. This way you don't have to pass a callback function from TestComponent
to onClickHandler
method in App
component.
Change onClickHandler
method to:
onClickHandler(id) {
return new Promise((resolve, reject) => {
setTimeout(resolve, 3000);
});
}
and change TestComponent
to:
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 (
{showProgress ? (
In Progress
) : (
)}
);
};
Demo
Отредактируйте Practical-sinoussi-r92qj