{ tweets: tweets.data }
const reducer = (state = { tweets: tweets.data }, action) => {
switch (action.type) {
case 'DELETE': {
return {
...state,
tweets: state.tweets.filter(value => value.id !== action.id),
};
}
default:
return state;
}
};
.user-logout {
border-top: 5px solid transparent;
background-clip: padding-box;
}
import { BrowserRouter, Route, Link, Switch } from 'react-router-dom';
export default class App extends Component {
render() {
return (
<BrowserRouter>
<div>
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/about'>About</Link></li>
<li><Link to='/contact'>Contact</Link></li>
</ul>
<hr/>
<Switch>
<Route exact path='/' component={Home}/>
<Route path='/about' component={About}/>
<Route path='/contact' component={Contact}/>
<Route path='/test/:id' component={HomePage}/>
</Switch>
</div>
</BrowserRouter>
);
}
}
export default class Home extends Component{
render(){
return(
<div>
<h1>Home</h1>
<div>
<ul>
<li><Link to='/test/1'>Фото на документы</Link></li>
<li><Link to='/test/2'>Принтер</Link></li>
<li><Link to='/test/3'>Печать на документы</Link></li>
</ul>
</div>
</div>
);
}
}
webpack -p
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}),
new webpack.optimize.UglifyJsPlugin({
// options
}),
plugins: [
new webpack.EnvironmentPlugin(['NODE_ENV']),
new webpack.optimize.UglifyJsPlugin({
// options
}),
],
new webpack.EnvironmentPlugin(['NODE_ENV']),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
}),
GET 'api/images?limit=20&page=1'
{
data: [...],
quantity: 500,
}
GET 'api/images?limit=20&page=2'
const hasMore = page * limit < total;
25 * 20 < 500 // false
const arr1 = ['a'];
const arr2 = ['b'];
const arr3 = [...arr1, ...arr2];
const arr4 = [...arr1, 1, ...arr2, 'c'];
console.log(arr3);
// => ['a', 'b'];
console.log(arr4);
// => ['a', 1, 'b', 'c'];
const obj1 = { a: 'a', b: 'old b' };
const obj2 = { b: 'new b', c: 'c' };
const obj3 = { ...obj1, ...obj2 };
const obj4 = { ...obj2, ...obj1 };
const obj5 = { ...obj1, ...obj2, d: 'd' };
console.log(obj3);
// => { a: 'a', b: 'new b', c: 'c' };
console.log(obj4);
// => { a: 'a', b: 'old b', c: 'c' };
console.log(obj5);
// => { a: 'a', b: 'new b', c: 'c', d: 'd' };
this.props.tasks === nextProps.tasks; // true
export default function addDelete(state = initialState, action){
switch (action.type) {
case "ADD_TASK":
return {
...state,
tasks: [...state.tasks, {{id: action.id, time : action.time, task: action.task}}],
};
case "DELETE_TASK":
return {
...state,
tasks: [...state.tasks.filter(task => task.id != action.id)],
};
case "SET_ACSSES":
return {
...state,
add: !state.add,
};
default:
return state;
}
}
export default function add(time, task, id){
if(!task || !time){
return {
type: "SET_ERROR",
payload: "Error, invalid data"
};
}
return{
type: "ADD_TASK",
payload: {
id: id,
time: time,
task: task,
},
}
}
export const deleteTask = id => ({
type: 'DELETE_TASK',
payload: id,
});
export default function addDelete(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case "ADD_TASK":
return {
...state,
tasks: [...state.tasks, payload],
};
case "DELETE_TASK":
return {
...state,
tasks: [...state.tasks.filter(task => task.id != payload)],
};
case "SET_ACSSES":
return {
...state,
add: !state.add,
};
default:
return state;
}
}
export const getAccounts = (userID) => {
fetch(`${BASE_URL}/users/${userID}/accounts/`).then(resp => {
resp.json().then(accounts => accounts.Items[0].accounts);
})
}
export const getAccounts = userID =>
fetch(`${BASE_URL}/users/${userID}/accounts/`).then(resp => {
resp.json().then(accounts => accounts.Items[0].accounts);
});
response = yield call(getAccounts, userID);
import { fetchInitialDataApi } from './api';
const FETCH_DATA_REQUEST = 'FETCH_DATA_REQUEST';
const FETCH_DATA_SUCCESS = 'FETCH_DATA_SUCCESS';
const FETCH_DATA_ERROR = 'FETCH_DATA_ERROR';
const fetchDataRequest = () => ({ type: FETCH_DATA_REQUEST });
const fetchDataSuccess = data => ({
type: FETCH_DATA_SUCCES,
payload: data,
});
const fetchDataError = error => ({
type: FETCH_DATA_ERROR,
payload: error,
});
const fetchData => async dispatch => {
try {
dispatch(fetchDataRequest());
const { data } = await fetchDataApi();
dispatch(fetchDataSuccess(data));
} catch error {
dispatch(fetchDataError(error));
}
};
const initialState = {
data: {},
isLoading: false,
isError: false,
error: null,
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case FETCH_DATA_REQUEST:
return {
...state,
isLoading: true,
isError: false,
error: null,
};
case FETCH__DATA_SUCCESS:
return {
...state,
data: payload,
isLoading: false,
};
case FETCH_DATA_ERROR:
return {
...state,
isLoading: false,
isError: true,
error: payload,
};
default:
return state;
}
}
const employees = ['Bill', 'Matt', 'Sarah'];
return (
<ul>
{employees.map((employee, i) => (
<li key={i}>employee</li>
)}
<ul>
);
<ul>
<li>Bill</li>
<li>Matt</li>
<li>Sarah</li>
</ul>
class Example extends Component {
state = {
elements: [],
page: 1,
limit: 20,
total: 0,
isLoading: false,
isError: false,
};
componentDidMount() {
this.loadThumbnails();
}
loadThumbnails = () => {
const { page, limit } = this.state;
this.setState({
isLoading: true,
isError: false,
}, () => {
axios.get(
`api/somePath?limit=${limit}&page=${page + 1}`
).then(response => {
const { data: { elements, total } } = response;
this.setState(prevState => ({
elements: [
...prevState.elements,
...elements
],
page: page + 1,
isLoading: false,
total,
}));
}).catch(error => {
this.setState({
isLoading: false,
isError: true,
});
});
});
};
render() {
const {
elements,
page,
limit,
total,
isLoading,
} = this.state;
const hasMore = page * limit < total;
return(
<MasonryInfiniteScroller
hasMore={hasMore}
loadMore={this.loadThumbnails}
>
{elements.map(element => (
<img
key={element.id}
src={element.thumbnail}
style={{
width: element.width + 'px',
height: element.height + 'px',
}}
/>
)}
{isLoading && <div>...Loading</div>}
{isError && (
<div>
Can't load data. Please, check your internet connection.
<button onClick={this.loadThumbnails}>
Try again
</button>
</div>
)}
</MasonryInfiniteScroller>
);
}
}
handleClick => e {
console.log(this.ourDiv);
};
<div
style={this.state.move}
onClick ={() => this.handleClick()}
ref={ourDiv => this.ourDiv = ourDiv}
></div>
import { fetchInitialDataApi } from './api';
const FETCH_INITIAL_DATA_REQUEST = 'FETCH_INITIAL_DATA_REQUEST';
const FETCH_INITIAL_DATA_SUCCESS = 'FETCH_INITIAL_DATA_SUCCESS';
const FETCH_INITIAL_DATA_ERROR = 'FETCH_INITIAL_DATA_ERROR';
const fetchInitialDataRequest = () => ({ type: FETCH_INITIAL_DATA_REQUEST });
const fetchInitialDataSuccess = data => ({
type: FETCH_INITIAL_DATA_SUCCES,
payload: data,
});
const fetchInitialDataError = error => ({
type: FETCH_INITIAL_DATA_ERROR,
payload: error,
});
const fetchInitialData => async dispatch => {
try {
dispatch(fetchInitialDataRequest());
const { data } = await fetchInitialDataApi();
dispatch(fetchInitialDataSuccess(data));
} catch error {
dispatch(fetchInitialDataError(error));
}
};
const initialState = {
data: {},
isLoading: false,
isError: false,
error: null,
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case FETCH_INITIAL_DATA_REQUEST:
return {
...state,
isLoading: true,
isError: false,
error: null,
};
case FETCH_INITIAL_DATA_SUCCESS:
return {
...state,
data: payload,
isLoading: false,
};
case FETCH_INITIAL_DATA_ERROR:
return {
...state,
isLoading: false,
isError: true,
error: payload,
};
default:
return state;
}
}
export default (state = window._data) => state;
componentDidMount() {
this.initSocket();
}
initSocket() {
// set user
socket.on('init', data => {
this.setState({
player: data.nickname,
}, () => {
alert(this.state.player);
});
});
}
render() {
const { user } = this.state;
if (!user) return <Loader />
return (
...
);
}
module: {
loaders: [
{
test: /\.jsx?$/,
loader: 'babel-loader?presets[]=es2015,presets[]=react,presets[]=stage-0'
},
...
]
}
module: {
rules: [
{
test: /\.js$/,
exclude: /\/node_modules\//,
use: [
{
loader: 'babel-loader',
options: {
presets: ['es2015', 'stage-0', 'react']
}
}]
},
...
]
}