Categories
React Answers

How to get something from the state or store inside a React Redux-Saga function?

To get something from the state or store inside a React Redux-Saga function, we call the select function.

For instance, we write

export const getProject = (state) => state.project;

// Saga
export function* saveProjectTask() {
  while (true) {
    yield take(SAVE_PROJECT);
    let project = yield select(getProject);
    yield call(fetch, "/api/project", { body: project, method: "PUT" });
    yield put({ type: SAVE_PROJECT_SUCCESS });
  }
}

to call select with the getProject to get the project state from the store.

Categories
React Answers

How to respond to the width of an auto-sized DOM element in React?

To respond to the width of an auto-sized DOM element in React,m we can use the react-measure hook.

To install it, we run

npm i react-measure

Then we use it by writing

import * as React from "react";
import Measure from "react-measure";

const MeasuredComp = () => (
  <Measure bounds>
    {({
      measureRef,
      contentRect: {
        bounds: { width },
      },
    }) => <div ref={measureRef}>My width is {width}</div>}
  </Measure>
);

to use the Measure component from react-measure to retuen the width of the div by assigning the measureRef provided as the value of the div’s ref prop.

Categories
React Answers

How to style components using makeStyles and still have lifecycle methods in React Material UI?

To style components using makeStyles and still have lifecycle methods in React Material UI, we call makeStyles outside our component.

And then we use the useStyles hook returned from makeStyles to apply the styles.

For instance, we write

import React, { useEffect, useState } from "react";
import axios from "axios";
import { Redirect } from "react-router-dom";

import { Container, makeStyles } from "@material-ui/core";

import LogoButtonCard from "../molecules/Cards/LogoButtonCard";

const useStyles = makeStyles((theme) => ({
  root: {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    margin: theme.spacing(1),
  },
  highlight: {
    backgroundColor: "red",
  },
}));

const Welcome = ({ highlight }) => {
  const [userName, setUserName] = useState("");
  const [isAuthenticated, setIsAuthenticated] = useState(true);
  const classes = useStyles();

  //...
  if (!isAuthenticated()) {
    return <Redirect to="/" />;
  }
  return (
    <Container
      maxWidth={false}
      className={highlight ? classes.highlight : classes.root}
    >
      <LogoButtonCard
        buttonText="Enter"
        headerText={isAuthenticated && `Welcome, ${userName}`}
        buttonAction={login}
      />
    </Container>
  );
};

export default Welcome;

to call makeStyles with an object with the class names set to objects with the styles for each class name.

Then we call useStyles in Welcome to return the classes object.

And then we apply the styles to Container from the classes object in the className prop.

Categories
React Answers

How to pass event with parameter with React onClick?

To pass event with parameter with React onClick, we set the onclick prop to a function that calls another function.

For instance, we write

const clickMe = (event, someParameter) => {
  //...
};


//... 

<button
  onClick={(e) => {
    clickMe(e, someParameter);
  }}
>
  Click Me!
</button>

to create the clickMe function.

Then we set the button’s onClick prop to a function that calls clickMe with the e event object and someParameter.

Categories
React Answers

How to handle CRUD in a form component with React and Redux?

To handle CRUD in a form component with React and Redux, we wrap the redux Provider around our app.

Then we can use Redux form to save form values in our Redux store.

For instance, we write

import React from "react";
import { createStore, combineReducers } from "redux";
import { Provider } from "react-redux";
import { modelReducer, formReducer } from "react-redux-form";

import MyForm from "./components/my-form-component";

const store = createStore(
  combineReducers({
    user: modelReducer("user", { name: "" }),
    userForm: formReducer("user"),
  })
);

class App extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <MyForm />
      </Provider>
    );
  }
}

to call createStore to create our store with the reducers created from combineReducers.

Then we write

mport React from "react";
import { connect } from "react-redux";
import { Field, Form } from "react-redux-form";

class MyForm extends React.Component {
  handleSubmit(val) {
    // ...
    console.log(val);
  }

  render() {
    let { user } = this.props;

    return (
      <Form model="user" onSubmit={(val) => this.handleSubmit(val)}>
        <h1>Hello, {user.name}!</h1>
        <Field model="user.name">
          <input type="text" />
        </Field>
        <button>Submit!</button>
      </Form>
    );
  }
}

export default connect((state) => ({ user: state.user }))(MyForm);

to add the Form component in MyForm to create a form with redux form.

And we add the Field component to add a field.

We set model to the path of the item we save in the store.