reactjs - การใช้ dispatch ในคอมโพเนนต์แบบคลาสทำให้เกิดข้อผิดพลาดในการเรียก hook ที่ไม่ถูกต้อง
ฉันเป็นมือใหม่ใน react-redux ฉันมีโค้ดนี้ ฉันกำลังใช้ react, redux และ TypeScript ในโค้ดนี้ใช้คอมโพเนนต์แบบคลาส และฉันต้องการใช้ dispatch เพื่อเรียก action เพื่อเพิ่มค่าของ counter แต่กลับทำให้เกิดข้อผิดพลาดดังต่อไปนี้
Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
นี่คือโค้ดคอมโพเนนต์แบบคลาสของฉัน:
import React from 'react';
import { connect, useDispatch } from 'react-redux';
import { Dispatch } from 'redux';
import { increment, decrement } from '../actions/counterAction';
interface IHome {
counter: 0
}
class Home extends React.Component<IHome> {
render() {
const dispatch = useDispatch();
return (
<div>
This is the home page {this.props.counter}
<button onClick={()=>dispatch(increment)}>+</button>
<button>-</button>
</div>
);
}
}
const mapStateToProps = (state: IHome) => {
return {
counter: state.counter
}
}
const mapDispatchToProps = (dispatch: Dispatch) => {
return {
increment: () => dispatch(increment()),
decrement: () => dispatch(decrement())
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Home);
ฉันไม่รู้ว่าปัญหาอยู่ที่ไหน
คำตอบ #1
ฮุก useDispatch() สามารถใช้ได้เฉพาะในคอมโพเนนต์แบบฟังก์ชันเท่านั้น
เนื่องจากคุณได้เชื่อมต่อคอมโพเนนต์ของคุณแล้ว คุณได้ส่ง action ของ redux (decrement และ increment) ไปยังคอมโพเนนต์ของคุณผ่านทาง props แล้ว
อย่างไรก็ตาม คุณจะต้องแก้ไขอินเทอร์เฟซ props ของคอมโพเนนต์ของคุณ เนื่องจากตอนนี้ TypeScript คิดว่าค่า prop ที่ถูกต้องเพียงค่าเดียวคือ counter
interface StoreProps {
counter: number
}
interface DispatchProps {
increment: () => void;
decrement: () => void;
}
type IHome = DispatchProps & StoreProps;
class Home extends React.Component<IHome> {
render() {
const { counter, increment, decrement } = this.props;
return (
<div>
This is the home page {counter}
<button onClick={()=>increment()}>+</button>
<button>-</button>
</div>
);
}
}
คำตอบ #2
Home เป็นคอมโพเนนต์แบบคลาส คุณต้องเปลี่ยนมันเป็นคอมโพเนนต์แบบฟังก์ชันถ้าคุณต้องการใช้ฮุคในนั้น ในกรณีนี้คุณสามารถลบการเรียกใช้ connect และ map... ออกและใช้ฮุค useStore สำหรับสโตร์ได้
export default const Home: React.FC<IHome> = () => {
const dispatch = useDispatch();
const store = useStore()
return (
<div>
This is the home page {store.getState().counter}
<button onClick={() => dispatch(increment())}>+</button>
<button>-</button>
</div>
);
}
