I'm new to React, ionic, tsx, etc. and I've seen a lot of stackoverflow and tutorials but can't find anything that I can transfer to my setup.
I'm trying to set a state in a class component to provide to child components so that they can use the useState hook to access a variable so that they can update the render after using setState in another component. Basically, I'm trying to get the login button in an IonHeader to authenticate the user using firebase. The component can then update the state via setState using the onAuthStateChanged hook. Other components in the IonContent can then use useState to get the callback and display their content or not, depending on whether the user is logged in or not. I might need to bind the class instance to the setState function so that children can access the function and state?
The problem I'm trying to solve is to synchronize states that individual child components can listen to and modify to alert other components to render with the new state. For the auth and db objects I can put them into their respective components.
I will replace "test: String" with the user from auth, if null then it will be an object. This way I can check if the user is logged in or not. It's all wrapped up in IonReactRoute and
States.tsx
export interface States extends React.PropsWithChildren{ db: Firestore, auth: Auth, test: String, }
Button.tsx
export const LoginButton: React.FC<States> = (children, props) => { return ( <Fragment> <div id='divLogin'> <button>login {props.test}</button> {props.children} </div> </Fragment> ) }
Home.tsx
export default class Home extends React.Component{ constructor(props) { super(props) // init firebase app initializeApp(firebaseConfig) // init services this.state = { db: getFirestore(), auth: getAuth(), test: 'teststring' } as States } render() { return ( <IonPage> {/* Header */} <IonHeader translucent> <IonToolbar> <IonTitle>Hydroponics-lurvas777</IonTitle> <LoginButton {...this.state}></LoginButton> {/*^^^^ this gives error: "Type '{}' is missing the following properties from type 'States': db, auth, test"*/} </IonToolbar> </IonHeader> <IonContent fullscreen> {/* Condense header for ios devices, larger to smaller header */} <IonHeader collapse="condense" translucent> <IonToolbar> <IonTitle size="large">Hej ios</IonTitle> </IonToolbar> </IonHeader> {/* Here's the real content, everything is toggles by auth state */} </IonContent> </IonPage> ); } };
I don't understand what's going wrong here, I wrapped the return into just one element and provided the child props via PropsWithChildren. If I add text inside the LoginButton I get "Type '{children: string; }' is missing the following properties from type 'States': db, auth, test". If I add any element in it the error message changes, so how can I add any child component in it? I think PropsWithChildren will solve this problem for me!
Not sure if this is a good solution or if it works, any feedback is appreciated!
P粉7665209912024-03-30 00:05:15
The reason why "Type '{}'
etc. is displayed is because the state
field inherits from React.Component
By default, this. state
is of type Readonly<{}>
, and when you expand it like {...this.state}
> the result is of type {}
.
Your use of as States
does not change the type of this.state
. This is similar to how in let A: Superclass = B as Subclass
, the type of A
will be Superclass, not Subclass.
One way to solve the input problem is to override the type of the state
field.
export default class Home extends React.Component{ state: States constructor(props: Props) { ... } ... }
Another approach is to explicitly specify the type parameters of the generic React.Component
, where P
represents props and S
code> is used state.
export default class Home extends React.Component{ constructor(props: Props) { ... } ... }