React.createClass
was deprecated in v15.5 and expected to be removed in v16. There is a drop-in replacement package for those that still require it. Examples using it should be updated.
NOTE: As of React 15.5 and up the PropTypes component lives in its own npm package, namely 'prop-types' and needs its own import statement when using PropTypes. See the official react documentation for the breaking change: https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html
This build pipeline is not exactly what you would call "production ready" but it does give a solid start for you to add on to it the things that you need in order to get the development experience you're looking for. The approach that some people take (including myself at times) is to take a fully built up pipeline of Yeoman.io or somewhere else and then strip off the things they don't want until it suits there style. There's nothing wrong with this but perhaps with the example above you could opt for the opposite approach and build up from bare bones.
Some things you might like to add are things like a testing framework and coverage statistics like Karma with Mocha or Jasmine. Linting with ESLint. Hot module replacement in webpack-dev-server so that you can get that Ctrl+S, F5 development experience. Also the current pipeline only builds in dev mode so a production build task would be good.
Gotchas!
Notice in the context property of the webpack.config.js
we have used the node path module to define our path rather than just concatenating __dirname
to the string /src
this is because windows hates forward slashses. So to make the solution more cross platform compatible use leverage node to help us.
Explanation of webpack.config.js properties
context
This is the filepath for which webpack will use as it's root path for the purposes of resolving relative file paths. So in index.jsx where we use require('./index.html')
that dot actually resolves to the src/
directory because we've defined it as such in this property.
entry
Where webpack looks first to begin bundling the solution. This is why you'll see that in the index.jsx we are stitching together the solution with requires and imports.
output
This is where we define where webpack should be dropping the file files it has found to bundle. We have also defined a name for the file in which our bundled javascript and styles will be dropped.
devServer
These are settings specific to webpack-dev-server. The contentBase
defines where the server should make it's root, we've defined the dist/
folder as our base here. The port
is the port that the server will be hosted on. open
is what is used to instruct webpack-dev-server to open your default browser for you once it's spun up the server.
module > loaders
This defines a mapping for webpack to use so that is knows what to do when it finds different files. The test
property gives regex for webpack to use to determine if it should apply this module, in most cases we've matches on file extensions. loader
or loaders
give the name of the loader module that we'd like to use to load the file into webpack and let that loader take care of the bundling of that file type. There is also a query
property on the javascript, this just provides a query string to the loader, so we could have probably used a query property on the html loader as well if we wanted to. It's just a different way of doing things.
React.createClass
was deprecated in v15.5 and expected to be removed in v16. There is a drop-in replacement package for those that still require it. Examples using it should be updated.
There are a total of 3 cases of communication between React components:
Stateless functional components in React are pure functions of the passed in props
. These components do not rely on state and discard the use of component lifecycle methods. You may, however, still define propTypes
and defaultPropts
.
See https://facebook.github.io/react/docs/reusable-components.html#stateless-functions for further information about stateless functional components.
JSX is a preprocessor step that adds XML syntax to JavaScript. You can definitely use React without JSX but JSX makes React a lot more elegant.
Just like XML, JSX tags have a tag name, attributes, and children. If an attribute value is enclosed in quotes, the value is a string. Otherwise, wrap the value in braces and the value is the enclosed JavaScript expression.
Fundamentally, JSX just provides syntactic sugar for the React.createElement(component, props, ...children)
function.
So, the following JSX code:
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
ReactDOM.render(<HelloMessage name="Kalo" />, mountNode);
Compiles down to the following JavaScript code:
class HelloMessage extends React.Component {
render() {
return React.createElement(
"div",
null,
"Hello ",
this.props.name
);
}
}
ReactDOM.render(React.createElement(HelloMessage, { name: "Kalo" }), mountNode);
In conclusion, note that the following line in JSX is neither a string nor HTML:
const element = <h1>Hello, world!</h1>;
It is called JSX, and it is a syntax extension to JavaScript. JSX may remind you of a template language, but it comes with the full power of JavaScript.
The React team says in their docs that they recommend using it to describe what the UI should look like.
Flux is the application architecture that Facebook uses for building client-side web applications. It complements React's composable view components by utilizing a unidirectional data flow. It's more of a pattern rather than a formal framework, and you can start using Flux immediately without a lot of new code.
Flux applications have three major parts: the dispatcher, the stores, and the views (React components). These should not be confused with Model-View-Controller. Controllers do exist in a Flux application, but they are controller-views — views often found at the top of the hierarchy that retrieve data from the stores and pass this data down to their children. Additionally, action creators — dispatcher helper methods — are used to support a semantic API that describes all changes that are possible in the application. It can be useful to think of them as a fourth part of the Flux update cycle.
Flux eschews MVC in favor of a unidirectional data flow. When a user interacts with a React view, the view propagates an action through a central dispatcher, to the various stores that hold the application's data and business logic, which updates all of the views that are affected. This works especially well with React's declarative programming style, which allows the store to send updates without specifying how to transition views between states.
To get syntax highlighting in your editor (e.g. VS Code) you'll need to download typing information for the modules that you use in your project.
Say for example you use React and ReactDOM in your project, and you want to get highlighting and Intellisense for them. You will need to add the types to your project using this command:
npm install --save @types/react @types/react-dom
Your editor should now automatically pick up on on this typing information and supply you with autocomplete and Intellisense for these modules.
For more information, visit this link to read how to use keys: https://facebook.github.io/react/docs/lists-and-keys.html
And visit this link to read why it is recommended to use keys: https://facebook.github.io/react/docs/reconciliation.html#recursing-on-children
Using the array index as a key is generally not recommended when the array is going to change over time. From the React Docs:
As a last resort, you can pass item's index in the array as a key. This can work well if the items are never reordered, but reorders will be slow.
A good example about this: https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318
HOCs are pretty often used in third party libraries. Such as the Redux connect function.
While React's component driven architecture is fantastic for breaking down the application into modular, encapsulated little pieces, it introduces some challenges for managing the state of the application as a whole. The time to use Redux is when you need to display the same data across more than one component or page (aka route). At that point you can no longer store the data in variables local to one component or the other, and sending messages between components quickly becomes a mess. With Redux your components are all subscribing to the same shared data in the store and thus the state can be easily reflected consistently across the entire application.