![](/img/trans.png)
[英]How to implement a check all button for radio buttons, using React Hooks?
[英]how to implement a refresh button with React Hooks?
我正在尝试实现刷新按钮,但无法完成。
这是我的代码的样子:
// ParentComponent.js
const ParentComponent = () => {
const { loading, error, data } = useItems();
return (
<ChildComponent items={data} />
);
... rest of my code that shows the data
};
// ChildComponent.js
const ChildComponent = ({ items }) => {
return (
// Logic that renders the items in <li>s
<button onClick={() => console.log('Clicking this button should refresh parent component')}
)
};
// services/useItems.js
const useItems = () => {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
axios
.get(API_URL + '/counter')
.then((response) => {
setItems(response.data);
setLoading(false);
})
.catch((error) => {
setLoading(false);
setError(error.message);
});
}, []);
return { loading, error, data: counters };
}
我尝试了几种方法,但都没有奏效。 任何帮助将不胜感激:)
我不认为useEffect
是这里的正确机制。 由于它是一个命令式调用,没有任何反应, useState
可以很好地完成工作:
// ParentComponent.js
const ParentComponent = () => {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
const refresh = () => {
axios.get(API_URL + '/counter').then((response) => {
setItems(response.data);
setLoading(false);
}).catch((error) => {
setLoading(false);
setError(error.message);
});
};
useEffect(refresh, []);
return (
<ChildComponent items={items} refresh={refresh} />
);
// ... rest of my code that shows the data
};
// ChildComponent.js
const ChildComponent = ({ items, refresh }) => {
return (
// Logic that renders the items in <li>s
<button onClick={refresh}>
Refresh
</button>
)
};
有几个小部件需要您进行更改以解决问题。
refresh
的通信
click
useItem
挂钩中添加一个函数refreshData
并公开它useEffect
setItems
仅在钩子内部可用。以下是一个工作示例:
const { useState, useEffect } = React; // ParentComponent.js const ParentComponent = () => { const { loading, error, data, refreshData } = useItems(); const refreshFn = () => { refreshData() } return ( <ChildComponent items={data} onClick={refreshFn}/> ); // ... rest of my code that shows the data }; // ChildComponent.js const ChildComponent = ({ items, onClick }) => { const onClickFn = () => { console.log('Clicking this button should refresh parent component') if(!!onClick) { onClick(); } } return ( // Logic that renders the items in <li>s <div> <button onClick={ () => onClickFn() } >Refresh</button> <ul> { items.map((item) => <li key={item}>{item}</li>) } </ul> </div> ) }; // services/useItems.js const useItems = () => { const [items, setItems] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); const [refresh, setRefresh] = useState(false) useEffect(() => { if (refresh) { setItems(Array.from({ length: 5 }, () => Math.random())); setRefresh(false) } }, [ refresh ]); return { loading, error, data: items, refreshData: () => setRefresh(true) }; } ReactDOM.render(<ParentComponent/>, document.querySelector('.content'))
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div class='content'></div>
一个非常简单的技巧是增加一个整数状态,我们称之为version
,这将触发<ParentComponent />
的重新渲染,如果useEffect
依赖于version
,它将重新执行回调,所以你得到“刷新”效果。
// ParentComponent.js
const ParentComponent = () => {
const [version, setVersion] = useState(0)
// when called, add 1 to "version"
const refresh = useCallback(() => {
setVersion(s => s + 1)
}, [])
const { loading, error, data } = useItems(version);
return (
<ChildComponent items={data} refresh={refresh} />
);
};
// ChildComponent.js
const ChildComponent = ({ items, refresh }) => {
return (
// Logic that renders the items in <li>s
<button onClick={refresh} />
)
};
// services/useItems.js
const useItems = (version) => {
const [items, setItems] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
axios
.get(API_URL + '/counter')
.then((response) => {
setItems(response.data);
setLoading(false);
})
.catch((error) => {
setLoading(false);
setError(error.message);
});
}, [version]); // <-- depend on "version"
return { loading, error, data: counters };
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.