Abstract: As most of you know, React has become more and more popular for modern web development. Microsoft is going to standardize the UI with React in SharePoint as well. Redux is a framework that is responsible for managing the state for most the of popular front-end frameworks, such as React, Angular, etc. You can build web parts alongside any of them. For example, you can use React along with the React component from Office UI Fabric React to quickly create experiences based on the same components used in Office 365. In this post, I will work through how to use React and Redux to implement a web part.
I assume you already know the basics of React, Redux, and TypeScript, so in this blog I will not introduce them. Please refer to the following sites to get familiar with them prior to reading this blog.
Gulp: A task and build manager that provides automation for build tasks, which is like MS build.
Yeoman: A Scaffolding tool for development projects, which helps us kick-start new projects, and prescribes best practices and tools to help you stay productive. SharePoint client-side development tools include a Yeoman generator for creating new web parts. The generator provides common build tools, common boilerplate code, and a common playground web site to host web parts for testing.
To get started on our environment setup, let’s install the latest version of Node. It is very straightforward and simple to install Node.js on Windows, Linux or Mac OS, just go to Node.js office and download and install it.
Visual Studio Code
Install a code editor. You can use any code editor or IDE that supports client-side development to build your web part, such as Atom, WebStorm, Visual Studio Code, etc. In this post, let’s use visual studio code as the editor.
Install Yeoman and gulp
Install Yeoman SharePoint generator
Scaffolding Project Structure with Yeoman SharePoint template
Create a new project directory in your favorite location.
Go to the project directory.
Create a new React-Redux web part by running the Yeoman SharePoint Generator.
Choosing a Global Software Development Partner to Accelerate Your Digital Strategy
To be successful and outpace the competition, you need a software development partner that excels in exactly the type of digital projects you are now faced with accelerating, and in the most cost effective and optimized way possible.
Get the Guide
- Enter React-Redux as your solution name and choose Enter.
- Select Use the current folder for where to place the files.
The next set of prompts will ask for specific information about your web part:
- Select WebPart as the type of client-side component we want to create.
- Enter React-Redux as your web part name and choose Enter.
- Enter some information as your web part description and choose Enter.
- Select React as the framework we would like to use.
Press Enter, it will take several minutes to finishing scaffolding the project structure, finally enter “code .”, then the new project will be opened with Visual Studio Code.
And it should look like this:
Yeoman not only created the basic folder structure but also downloaded packages we need in our SPFx development, such as react, react-dom, Webpack, sp-core-library, sp-webpart-base, etc. In the root project folder, there are several JSON format config files or js files. .yo-rc is for Yeoman, gulpfile.js is for gulp, tsconfig.json is for TypeScript. The src folder is where we will mainly be working. As you see, each web part will have a sub folder named components under webparts sub folder, which I want to place all presentation components in. As a best practice, I will create three other react-redux related folders under react-redux web part folder as well.
- container: container components are concerned with behavior, marshaling data, and actions, so all container components live in it.
- reducers: all reducers live in it.
- store: redux store will be defined in it.
Now, the struct should look like below:
Before we write some code with React and Redux, let’s briefly go through how React and Redux work together. The following figure shows how React and Redux work together.
Start React and Redux in Web Part
Presentational components focus on the UI rather than the behavior. So it’s important to avoid using state in presentational components. Yeoman already helped us created a presentational component based on the information we typed in the previous steps. Let’s tweak it a little bit. We define an interface called IGreeterProps, which tells the Greeter component what type of properties should valid. From the definition of this interface, we know that the parent container component should pass down an object which is this type of interface.
Container components are concerned with behavior, marshaling data, and actions. So these components have little or no markup. You can think of container components as the back-end of the front-end, Container components are primarily concerned with passing data and actions down to their children. This means they’re typically stateful. When working in Redux, container components are typically created using Redux’s connect function at the bottom of the file. React-Redux’s Connect function accepts two parameters both of which are functions, and both parameters are optional. The first parameter is mapStateToProps. This function is useful for defining what part of the Redux store you want to expose on your component. When you define this function, the component will subscribe to Redux store updates. Any time it updates, mapStateToProps will be called. This function returns an object. Each property on the object you define will become a property on your container component. So in summary, the mapStateToProps function determines what state is available on your container component via props.
In our case, this function will return an object which contains a name property and disableReactive property, the name will be passed down to dumb component Greeter and ReactiveInfo we have created previously.
Perform logic with an action creator:
The action creator layer is where we’ll perform all Ajax requests and other internal logic to fetch or prepare data for the reducer. In our case, we defined two action creators, one is updateProperty which returns an IUpdatePropertyAction type of action object, another is applyProperties which returns an IApplyPropertiesAction type of action object.
The reducer builds the final state object:
The reducer’s responsibility is to manage the application state and changes coming from the action creators and clone the current state with changes to the new state. It is important to note that the reducer is a pure function, which means it should not mutate the current application state. Instead, it should make a copy of the current state and apply the changes to it when changes come from actions. In our case, we defined reducer for the web part, when changes come from actions, reducer will clone a new copy of current state with new changes applied.
Note: we use assign of lodash to clone the current state and return it as the result of the reducer. More information about assign, please refer to lodash assign.
Here we define a store which will be passed down to the Provider component of react-redux. We initialize a middleware for logging and also use combine reducers to manage the sub state tree related to web parts. This unique store will be subscribed by container component and refreshed by reducers.
Dispatch an action
Yeoman help us create an outermost wrapper component inherited from BaseClientSideWebPart. BaseClientSideWebPart is developed by the Microsoft team and provides the most common events, such as onPropertyChanged, onInit and onAfterPropertyPaneChangedApplied, etc. This wrapper component is the entry of the web part app. So, let’s initial the container web part inside of it. In the Render function, we use the Provider of react-redux to pass down the unique store to the container component.
In property changed event callback, we pass in the action returned from applyProperties (this.properties) to store.dispatch function, then the reducer receives the action and clones a new version of state with the the property changed, then the changed property value will be passed down by container component to presentation component. Finally, the UI will change.
How it looks
Let’s bring up the terminal and run gulp serve to see what the web part looks like. When I change the name property on the right-hand side, it will be reflected in the text box on the left-hand side.
All right, we have created a sample web part which two React components, which consists of a presentation component and a container component. We also used redux to manage the state by a unique store graph. I strongly recommend going through some basic knowledge of react, redux, react-redux before using them in SharePoint Framework development. There are a lot of features we did not mention here, such as Anyc Ajax call with thunk middleware, testing react component, react routes, etc. The good news is we have a good start when we complete our own app with React and Redux. Let’s dive more into react and redux more in the SharePoint Framework development as well as modern web development.
Set up your SharePoint client-side web part development environment
SharePoint Framework client-side web part samples & tutorial materials