React Table of content




Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


React Update State

How to update state of an object

We have a user object

setUser({
  ...user,
  name: "Peter"
});

 

How to update state of list/array of objects

We have a shopping cart which contains a list of menu items

const [shopCart, setShopCart] = useState([{
  name: "",
  price: 0,
  uuid: ""
}]);


add item to shopping cart

const addMenuItemToCart = (menuItem: any) => {
  console.log("addMenuItemToCart, ", menuItem)

  setShopCart(shopCart => {
    shopCart.push(menuItem);
    const newState = shopCart.map(obj => {
      // 👇️ otherwise return object as is
      return obj;
    });

    return newState;
  });

}

 

 

 

September 5, 2020

React with Bootstrap

Install Bootstrap

npm install --save bootstrap

Include bootstrap.css in the index.js

import 'bootstrap/dist/css/bootstrap.css';

 

 

August 7, 2019

React Keys

React keys are useful when working with dynamically created components or when your lists are altered by the users. Setting the key value will keep your components uniquely identified after the change.

import React from 'react';

class App extends React.Component {
   constructor() {
      super();
        
      this.state = {
         users:[
            {
               name: 'Folau',
               id: 1
            },
            {
               name: 'Lisa',
               id: 2
            }
         ]
      }
   }
   render() {
      return (
         <div>
            <div>
               {this.state.data.map((user, i) => 
                <h4>My name is {user.name}<h4/>
               )}
            </div>
         </div>
      );
   }
}

It’s strongly recommended that you assign proper keys whenever you build dynamic lists. If you don’t have an appropriate key, you may want to consider restructuring your data so that you do.

If no key is specified, React will present a warning and use the array index as a key by default. Using the array index as a key is problematic when trying to re-order a list’s items or inserting/removing list items. Explicitly passing key={i} silences the warning but has the same problems as array indices and is not recommended in most cases.

Keys do not need to be globally unique; they only need to be unique between components and their siblings.

 

August 7, 2019

React Route

Install router

npm install –save react-router-dom

yarn add react-router-dom

In the index.js

import { BrowserRouter as Router, Route } from “react-router-dom”;
ReactDOM.render(
 <Providerstore={createStore(allReducers, applyMiddleware(thunk))}>
  <React.StrictMode>
  <Router>
  <Routepath=”/”exactcomponent={Home}/>
  <Routepath=”/login”exactcomponent={Login}/>
  <Routepath=”/signup”exactcomponent={Signup}/>
  <Routepath=”/profile”exactcomponent={ProfilePage}/>
  <Routepath=”/about”exactcomponent={AboutPage}/>
  <Routepath=”/photos”exactcomponent={PhotosPage}/>
  <Routepath=”/friends”exactcomponent={FriendsPage}/>
  </Router>
 </React.StrictMode>
 </Provider>,
document.getElementById(‘root’)
);

 

 

August 7, 2019

React Redux

Install redux

npm install react-redux

Add redux to index.js file

React Redux provides <Provider/>, which makes the Redux store available to the rest of your app

import React from 'react'
import ReactDOM from 'react-dom'
import thunk from 'redux-thunk'
import {createStore, applyMiddleware} from 'redux'
import { Provider } from 'react-redux'
import store from './store'
import allReducers from './redux/reducers/allReducer.js'
import App from './App'

const rootElement = document.getElementById('root')

ReactDOM.render(
  <Provider store={createStore(allReducers, applyMiddleware(thunk))}>
    <App />
  </Provider>,
  rootElement
)

Connect Component to store

React Redux provides a connect function for you to connect your component to the store.

import React, { Component } from 'react';
import { connect } from 'react-redux';
import LandingPage from './landing_page';
import Header from './header/header';
import Posts from './post/posts';
import LeftPanel from './left_panel';
import RightPanel from './right_panel';

class Home extends Component {

    constructor(props) {
        super(props);
        this.state = {
            userAuthenticated: localStorage.getItem('userUuid') ? true : false
        }
    }

    componentDidMount() {
    }

    render() {

        return (
            <div>
                <Header />
                <main>
                    <div className="main-wrapper pt-80">
                        <div className="container">
                            <div className="row">
                                <LeftPanel page="HOME"/>
                                <Posts page="HOME"/>
                                <RightPanel/>
                            </div>
                        </div>
                    </div>
                </main>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return state;
}

export default connect(mapStateToProps, {
})(Home);

Access data from the store

import React, { Component } from 'react';
import {connect} from 'react-redux';
import { loadNotifications } from '../redux/actions/NotificationAction';

class RecentNotifications extends Component {

    constructor(props) {
        super(props);
        console.log("RecentNotifications constructor()");
        this.state = {
        }
    }

    componentDidMount(){
        
    }

    render() {
        console.log("RecentNotifications render()");

        console.log(this.props.ntcsState.notificationInfo.content);

        let listOfNotifications = {};
        
        if(this.props.ntcsState.notificationInfo.content!==undefined && this.props.ntcsState.notificationInfo.content!==null){
            listOfNotifications = this.props.ntcsState.notificationInfo.content.map((notification) =>

                <li key={notification.uuid} className="unorder-list">
                    {/* profile picture end */}
                    <div className="profile-thumb">
                        <a href="/">
                            <div className="profile-thumb-small">
                                <img src={notification.createdBy.profileImageUrl} alt="profile" />
                            </div>
                        </a>
                    </div>
                    {/* profile picture end */}

                    <div className="unorder-list-info">
                        <h3 className="list-title"><a href="/">Any one can join with us if you want</a></h3>
                        <p className="list-subtitle">5 min ago</p>
                    </div>
                </li>
            );
        }else{
            listOfNotifications = <li className="unorder-list"></li>
        }

        return (
            <div className="card widget-item">
                <h4 className="widget-title">Recent Notifications</h4>
                <div className="widget-body">
                    <ul className="like-page-list-wrapper">
                        {listOfNotifications} 
                    </ul>
                </div>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    return state;
}

export default connect(mapStateToProps,{
    loadNotifications: loadNotifications
})(RecentNotifications);

You can access data from the store by connecting to the store and using props like this.props.ntcsState.

NotificationReducer.js

const notificationInitialState = {
    notificationInfo: {}
};

let notificationInfo;

export const NotificationStateReducer = (state = notificationInitialState, action) => {

    switch (action.type) {
        case 'LOAD_NOTIFICATIONS':

            notificationInfo = action.payload;

            //console.log("LOAD_NOTIFICATIONS");
            //console.log(notificationInfo.data);

            return Object.assign({}, state, {
                notificationInfo: notificationInfo.data
            });

        default:
            return state;
    }
}

NotificationAction.js

import NotificationAPI from '../../api/notification';

export const loadNotifications = () => {

    let userUuid = localStorage.getItem("userUuid");
    let pageSize = 10;
    let pageNumber = 0;

    //console.log("LOAD_NOTIFICATIONS");

    return async function(dispatch, getState) {
        const response = await NotificationAPI.getNotifications(userUuid, pageSize, pageNumber);
        dispatch({ type: "LOAD_NOTIFICATIONS", payload: response });
    };
};

 

Trigger actions in the store

import React, { Component } from 'react';
import Avatar from '../images/avatar.png';
import UserAPI from '../api/user';
import { connect } from 'react-redux';
import { setUserSession } from '../redux/actions/UserAction';

class ProfileUpdate extends Component {

    constructor(props) {
        super(props);
        this.state = {
            profile: {
                firstName: "",
                lastName: "",
                email:"",
                phoneNumber:"",
                gender: "",
                maritalStatus: "",
                profileImageUrl: props.userState.userProfileImageUrl!== null ? props.userState.userProfileImageUrl : Avatar,
                coverImageUrl: props.userState.userCoverImageUrl!== null ? props.userState.userCoverImageUrl : Avatar,
                uploadImage:""
            }
        }

        this.loadProfile = this.loadProfile.bind(this);
        this.handleInputChange = this.handleInputChange.bind(this);
        this.updateProfile = this.updateProfile.bind(this);
    }

    componentDidMount() {
    }

    handleInputChange(event) {
        console.log("handleInputChange");
        const target = event.target;
        const value = target.type === 'checkbox' ? target.checked : target.value;
        const name = target.name;

        if(name==="profileImageFile"){
            console.log("upload profile image");

            const formData = new FormData(); 
            formData.append( 
                "file", 
                event.target.files[0], 
                event.target.files[0].name 
            ); 

            let uuid = localStorage.getItem("userUuid");

            UserAPI.uploadProfileImage(uuid, formData)
            .then(response => {
                console.log("response");
                console.log(response.data);

                let user = response.data;

                this.setState({profile:user},()=>{});

                this.props.setUserSession(user);

            }).catch(error => {
                console.log("error");
                console.log(error.response.data);
            });
            return;
        }

        if(name==="coverImageFile"){
            console.log("upload cover image");

            const formData = new FormData(); 
            formData.append( 
                "file", 
                event.target.files[0], 
                event.target.files[0].name 
            ); 

            let uuid = localStorage.getItem("userUuid");

            UserAPI.uploadCoverImage(uuid, formData)
            .then(response => {
                console.log("response");
                console.log(response.data);

                let user = response.data;

                this.setState({profile:user},()=>{});

                this.props.setUserSession(user);

            }).catch(error => {
                console.log("error");
                console.log(error.response.data);
            });
            return;
        }

        let updatedState = {
            profile: this.state.profile
        }

        updatedState['profile'][name] = value;

        console.log("updated state");
        console.log(updatedState);

        this.setState(updatedState, function () {
            //console.log(this.state);
        });
    }

    loadProfile(event){

        let uuid = localStorage.getItem("userUuid");

        UserAPI.getProfile(uuid)
        .then(response => {
        console.log("response");
        console.log(response.data);

        let user = response.data;

        this.setState({profile: user});

        this.props.setUserSession(user);

        }).catch(error => {
            console.log("error");
            console.log(error.response.data);
        });
    }

    updateProfile(event){
        
        console.log(this.state.profile);

        UserAPI.updateProfile(this.state.profile)
        .then(response => {
            console.log("response");
            console.log(response.data);

            let user = response.data;

            this.setState({profile: user});

            this.props.setUserSession(user);

        }).catch(error => {
            console.log("error");
            console.log(error.response.data);
        });
    }

    render() {
        return (
            <div className="col-lg-2 col-md-3 d-none d-md-block">
                <div className="profile-edit-panel">
                    <button onClick={this.loadProfile} className="btn-adda edit-btn" data-toggle="modal" data-target="#profileUpdateModal" >edit profile</button>
                </div>
                <div className="modal fade in" id="profileUpdateModal" aria-labelledby="profileUpdateModal">
                    <div className="modal-dialog">
                        <div className="modal-content">
                            <div className="modal-header">
                                <h5 className="modal-title">Update Profile</h5>
                                <button type="button" className="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
                            </div>
                            <div className="modal-body custom-scroll">
                                <div className="row">
                                    <div className="col-sm-12 text-center">
                                        <img src={this.state.profile.profileImageUrl} className="rounded" alt="..."/>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="col-sm-6 offset-sm-3">
                                        <div className="form-group text-center">
                                            <input type="file" className="form-control-file"
                                             name="profileImageFile"
                                             onChange={this.handleInputChange}
                                             />
                                        </div>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="col-sm-12 text-center">
                                        <img src={this.state.profile.coverImageUrl} className="rounded" alt="..."/>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="col-sm-6 offset-sm-3">
                                        <div className="form-group text-center">
                                            <input type="file" className="form-control-file"
                                             name="coverImageFile"
                                             onChange={this.handleInputChange}
                                             />
                                        </div>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="col-sm-6">
                                        <div className="form-group">
                                            <label>First Name</label>
                                            <input type="text" className="form-control" aria-describedby="firstNameHelp" placeholder="Enter first name"
                                            name="firstName"
                                            onChange={this.handleInputChange}
                                            value={this.state.profile.firstName}/>
                                        </div>
                                    </div>
                                    <div className="col-sm-6">
                                        <div className="form-group">
                                            <label>Last Name</label>
                                            <input type="text" className="form-control" aria-describedby="lastNameHelp" placeholder="Enter last name"
                                            name="lastName"
                                            onChange={this.handleInputChange}
                                            value={this.state.profile.lastName}
                                            />
                                        </div>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="col-sm-6">
                                        <div className="form-group">
                                            <label>Email</label>
                                            <input type="email" className="form-control" aria-describedby="emailHelp" placeholder="Enter email"
                                            name="email"
                                            onChange={this.handleInputChange}
                                            value={this.state.profile.email}
                                            />
                                        </div>
                                    </div>
                                    <div className="col-sm-6">
                                        <div className="form-group">
                                            <label>Phone</label>
                                            <input type="tel" className="form-control" aria-describedby="phoneNumberHelp" placeholder="Enter phone number"
                                            name="phoneNumber"
                                            onChange={this.handleInputChange}
                                            value={this.state.profile.phoneNumber}
                                            />
                                        </div>
                                    </div>
                                </div>
                                <div className="row">
                                    <div className="col-sm-6">
                                        <div className="form-group">
                                            <label>Gender</label>
                                            <select className="form-control"
                                                name="gender"
                                                onChange={this.handleInputChange} 
                                                value={this.state.profile.gender}>
                                                <option value="MALE">Male</option>
                                                <option value="FEMALE">Female</option>
                                                <option value="TRANGENDER">Transgender</option>
                                            </select>
                                        </div>
                                    </div>
                                    <div className="col-sm-6">
                                        <div className="form-group">
                                            <label>Marital Status</label>
                                            <select className="form-control"
                                                name="maritalStatus"
                                                onChange={this.handleInputChange} 
                                                value={this.state.profile.maritalStatus}>
                                                <option value="SINGLE">Single</option>
                                                <option value="MARRIED">Married</option>
                                                
                                                
                                            </select>
                                        </div>
                                    </div>
                                </div>
                            </div>
                            
                            <div className="modal-footer">
                                <button type="button" className="btn-adda post-share-btn" data-dismiss="modal">cancel</button>
                                <button onClick={this.updateProfile} type="button" data-dismiss="modal" className="btn-adda post-share-btn">Update</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

const mapStateToProps = (state) => {
    //console.log("home all states", state)
    return state;
}

export default connect(mapStateToProps, {
    setUserSession: setUserSession
})(ProfileUpdate);

You use props to call actions like this 

this.props.setUserSession(user);

 

 

August 6, 2019