Constantly improving and updating. Because I use it on my own projects.
- Clone the project
git clone https://github.com/dizefurkan/reactjs-boilerplate.git
. - Install dependencies
npm install
- webpack
- css-loader
- file-loader
- html-loader
- style-loader
- mini-css-extract-plugin
- babel-core
- babel-eslint
- babel-loader
- babel-polyfill
- babel-preset-react
- eslint
- eslint-plugin-react
- eslint-config-airbnb
Folder | Description |
---|---|
dist | The build folder |
src | Source folder |
src/assets | For plugins. Like; bootstrap, jquery, fontawesome... |
src/components | For partitions. Like; Footer, Header... |
src/public | There are hosts in this folder; index.html |
src/services | Put files like helper, with fetch operations (MVC) |
src/utils | Keep files here like; form validations. |
src/views | This folder for pages like login page, register, 404, 500... |
You can see the DocumentTitle for page title on browser
Auth control for token
// src/app.js
class App extends Component {
...
render() {
const { auth } = this.state;
return (
<DocumentTitle title='React.js Boilerplate'>
<BrowserRouter>
<Switch>
<PrivateRoute
exact
path='/'
state={this.state}
modal={e => this.setModal(e)}
component={Home}
title='Home Page'
/>
<PropsRoute
path='/login'
state={this.state}
modal={e => this.setModal(e)}
component={Login}
title='Login Page'
/>
<PropsRoute
path='/register'
state={this.state}
modal={e => this.setModal(e)}
component={Register}
title='Register Page'
/>
<PropsRoute
path='/reset-password'
modal={e => this.setModal(e)}
component={ResetPassword}
title='Reset Password'
/>
<PropsRoute
path=''
component={NotFound404}
title='404 | Not Found'
/>
</Switch>
</BrowserRouter>
</DocumentTitle>
);
}
}
export default App;
// Private Component
...
class PrivateRoute extends Component {
render() {
if (!this.props.state.auth) { return <Redirect to='/login' />; }
return (
<DocumentTitle title={this.props.title}>
<div>
<Header state={this.props.state}/>
<PropsRoute
{...this.props}
/>
<Footer />
</div>
</DocumentTitle>
);
}
}
...
Local and Global styles with hashed classNames
import gbStyles from 'public/main.css'; //Global Styles
import styles from './styles.css'; //Local Styles
const Test = () => {(
<div className={gbStyles.clearfix}>
<h1 className={styles.title}>React.js Boilerplate</h1>
</div>
)};
output;
<html>
<body>
<div class="main__clearfix___34Arz">
<h1 class="styles__title___2m2w7">React.js Boilerplate</h1>
</div>
</body>
</html>
webpack.config.js;
localIdentName: "[name]__[local]___[hash:base64:5]"
Like joi but it was written by me
#####1) Create Your States
this.state = {
form: { // for keep input values
email: '',
password: '',
},
formMessage: { // for show error message to each input...
email: '',
password: '',
submit: '',
},
validation: { // boolean validation objects for each input
email: false,
password: false,
},
isAlertActive: false, // for <Alert /> component
};
#####2) Set Your Inputs on views/partitions/Form
export default {
login: [
{
type: 'text',
name: 'email',
title: 'Email',
placeholder: '[email protected]',
},
{
type: 'password',
name: 'password',
title: 'Password',
},
],
register: [...],
}
#####3) import views/partitions/Form and it will be auto implemented
<form onSubmit={e => this.onSubmit(e)}>
{
Form.login.map((item, index) => (
<div key={index} className={FormStyles.inputBox}>
<label className={FormStyles.label}>{item.title}</label>
<input
className={FormStyles.input}
onChange={e => this.onChange(e)}
{...item}
/>
</div>
))
}
<input
type='submit'
className={FormStyles.submit}
/>
</form>
#####4) Create functions
onChange(event) {
const { form } = this.state;
const { target: { value, name } } = event;
form[name] = value;
this.setState({ form });
}
async onSubmit(event) {
event.preventDefault();
const {
form,
validation,
formMessage,
} = this.state;
formMessage.submit = '';
this.setState({ formMessage });
Object.keys(form).map(key => this.controlFormValidity(key, form[key]));
this.setState({ isAlertActive: true, isSubmited: true });
if (isValidated(validation)) {
// When it passed...
}
}
controlFormValidity(fieldName, fieldValue) {
const formSubmitObj = formSchema(fieldName, fieldValue);
const result = formValidator(formSubmitObj);
const { validation, formMessage } = this.state;
setField(result, validation, formMessage);
}
<Alert
close={e => this.close(e)}
messages={<AlertMessage formMessage={formMessage} />}
/>
Show Alert (HOC)
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import styles from './styles.css';
class Alert extends Component {
render() {
return (
<div className={styles.alertBox}>
<div>{this.props.messages}</div>
<span className={styles.close} onClick={e => this.props.close(e)}>
<i className={`${styles.icon} far fa-window-close`}></i>
</span>
</div>
);
}
}
Alert.propTypes = {
messages: PropTypes.any,
close: PropTypes.func,
};
export default Alert;
Show Modal
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Grid, Row, Col } from 'react-bootstrap';
import styles from './styles.css';
class Modal extends Component {
render() {
return (
<div className={styles.modalBox}>
<div className={styles.filter}></div>
<Grid>
<Row>
<Col xs={12}>
<div
className={styles.closeBox}
onClick={this.props.onClick}
>
<span className={styles.close}>
✕
</span>
</div>
<div className={styles.box}>
{this.props.child}
</div>
</Col>
</Row>
</Grid>
</div>
);
}
}
Modal.propTypes = {
child: PropTypes.any.isRequired,
onClick: PropTypes.func.isRequired,
};
export default Modal;
Set Alias for Folder Path
import gbStyles from 'public/main.css'; //Global Styles
webpack.config.js;
resolve: {
alias: {
'public': path.resolve(__dirname, 'src/public/'),
}
}
You can see imported the plugins like Bootstrap or Fontawesome
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>REACTJS BOILERPLATE</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/src/assets/plugins/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="src/assets/plugins/font-awesome-5/css/fontawesome-all.min.css">
</head>
<body>
<div id="app"></div>
</body>
</html>