Nils
Nils

Reputation: 57

Mobx store in react doesn't rerender components

I'm trying to understand mobx. After annotations caused a lot of trouble, I decided to use a global store as described here. My store looks like this:

import {
    makeObservable,
    observable,
    action
} from "mobx";

class Store {
    constructor() {
        makeObservable(this, {
            fetchWorkouts: action,
            user: observable,
            allWorkouts: observable,
            selectedWorkout: observable,
            currentStep: observable,
            setUser: action
        })
    }

    user = {
        uid: null,
        email: null,
        name: null
    }

    allWorkouts = []

    selectedWorkout = {}

    currentStep = 0

    fetchWorkouts() {

    }

    setUser(newUser) {
        this.user = newUser;
    }

}

const store = new Store()

export default store;

My new user comes directly from the login, which looks like this:

import {Button} from "semantic-ui-react";
import {useHistory} from "react-router-dom"
import React from 'react';

import store from "../../context/Store";
import {toJS} from "mobx";

export default function SubmitLogin(props) {
    let history = useHistory();
    // eslint-disable-next-line react-hooks/exhaustive-deps
    const loginUser = async () => {
        let bodyObj = {
            email: props.email,
            pw: props.password
        }
        let queryString = "http://localhost:3001/user/login/" + bodyObj.email + "/" + bodyObj.pw;
        await fetch(queryString).then(response => response.json()).then(json => store.setUser(json)).then(() => console.log(toJS(store.user))).then(() => history.push("/"));
    }

    return (
        <>
            <Button className={"loginRegisterButton"} onClick={loginUser}>Submit</Button>
        </>
    )
}

To test everything, I am trying to display the uid in my header like this:

import React, {Component} from 'react';
import {Link} from "react-router-dom";

import store from "../context/Store";

class Toolbar extends Component {
    render() {
        return (
            <div id={"toolbarDiv"}>
                <p style={{color: "white"}}>{store.user.uid}</p>
            </div>
        );
    }
}

export default Toolbar

However, even after I receive the uid from my server and can print it in my login component, I assume that the data gets correctly assigned to the user variable in the store. Unfortunately, after pressing the sign in button and getting redirected to "/", there is nothing in the toolbar. How can I access the variables correctly?

Upvotes: 0

Views: 828

Answers (1)

Steven Than
Steven Than

Reputation: 454

I think you still need to wrap Toolbar and SubmitLogin in an observer call:

import React, {Component} from 'react';
import {Link} from "react-router-dom";
import { observer } from "react-mobx";

import store from "../context/Store";

class Toolbar extends Component {
    render() {
        return (
            <div id={"toolbarDiv"}>
                <p style={{color: "white"}}>{store.user.uid}</p>
            </div>
        );
    }
}

export default observer(Toolbar);

Ref: https://mobx.js.org/react-integration.html

Upvotes: 2

Related Questions