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);