this.props.children
. Вложенность роутов друг в друга - любая, можно таким образом еще усложнить логику отрисовки шаблона.<Route path='/reports' component={AuthenticatedContainer} onEnter={_ensureAuthenticated}>
<Route getComponent={() => def(import('../containers/WiwthSidebar'))}>
<Route path='/reports/a' getComponent={() => def(import('../containers/A'))} />
<Route path='/reports/b' getComponent={() => def(import('../containers/B'))} />
</Route>
<Route getComponent={() => def(import('../containers/WithoutSideber'))}>
<Route path='/reports/c' getComponent={() => def(import('../containers/C'))} />
</Route>
</Route>
function def(promise) {
return promise.then(cmp => {
console.info('Dynamic loaded by route: ', cmp.default.displayName) // для тестирования можете логировать имя компонента
return cmp.default
})
}
...
<Route path='/signin' getComponent={() => def(import('../containers/SigninContainer'))} />
...
ReactDOM.render(
<Router history={browserHistory}>
<Route path="/" component={Layout}>
<Route path="/sing" component={SignUp}/>
<Route path="/profile" component={Profile} />
<Route path="/register_approve" component={Validation} />
<Route path="/forgot_password" component={ForgotPassword} />
<Route path="/confirm_email" component={ConfirmEmail} />
<Route path="/restore_password/:token" component={RestorePassword} />
<Route path="/confirm_invite" component={ConfirmInvite} />
<Route path="/my-cabinet" component={Cabinet} />
<Route path="/members" component={Members} />
<Route path="/invite-member" component={InviteMember} />
<Route path="/not_access" component={NotAccess} />
<Route path="/finance" component={Finance}>
<Route path="/finance/project" component={FinanceProject}/>
<Route path="/finance/fixed-costs" component={FinanceFixedCost}/>
<Route path="/finance/fixed-costs" component={FinanceFixedCost}/>
<Route path="/finance/salary" component={FinanceSalary}/>
<Route path="/finance/other" component={FinanceOther}/>
</Route>
</Route>
<Route path="*" component={NotFound} />
</Router>,
document.getElementById('root')
return Object.keys(this.props.posts).map(postId => {
const currentPost = this.props.posts[postId]
return (
<li className="list-group-item" key={currentPost.id}>
<span className="pull-xs-right">{currentPost.categories}</span>
<strong>{currentPost.title}</strong>
</li>
);
})
Всякие красивые чекбоксы, радиобаттоны и прочие интерфейсы верстаю вручную, и естесственно адаптивно.
...
import configRoutes from '../../routes'
...
render() {
return (
<Provider store={store}>
<Router history={routerHistory}>
{configRoutes(store)}
</Router>
</Provider>
)
}
...
<Route path='/secret-area' component={SecretAreaContainer} onEnter={_ensureAuthenticated}>
...
export default function configRoutes(store) {
function _ensureAuthenticated(nextState, replace, callback) {
const { dispatch } = store
const { session } = store.getState()
const { currentUser } = session // данные по юзеру
let nextUrl
if (!currentUser && localStorage.getItem('token')) {
dispatch(getCurrentAccount())
}
} else if (!localStorage.getItem('token')) {
nextUrl = location.pathname + location.search.replace('?', '&')
replace('/signin')
}
callback()
}
// здесь ваши роуты
export function signIn(email, password) {
return (dispatch, getState) => {
dispatch({
type: USER_SIGN_IN_REQUEST,
})
const params = {
email,
password,
}
httpPost(`${API_ROOT_V1}/api/authenticate`, params)
.then((data) => {
saveParamsToLS(data) // здесь токен можно сохранить, например
dispatch(push('/account')) // ваш РЕДИРЕКТ, используется push из react-router-redux (что необязательно)
})
.catch((error) => {
console.warn(`Sign in error: ${JSON.stringify(error)}`) //eslint-disable-line no-console
dispatch({
type: USER_SIGN_IN_FAILURE,
error: error,
})
})
}
}
Но там, где он не нужен, все равно применялся.
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
renderTemplate(data) {
return data.map(item => .... )
}
render() {
...
{ this.props.data.length ? this.renderTemplate(this.props.data) : null }
...
}
function myFunc(data) { console.log(data) }
console.log( myFunc('test') ) => выведеть в консоль 'test'
console.log( myFunc ) => выведеть в консоль function myFunc ...
<Route path='/articles/:id' >
/articles/1
getArticles(this.props.params.id)
если в DidMount то контент может на некоторое время показаться без данных из сервера, или я не прав
// для примера обе переменные (store и dispatch) объявлены в той же области видимости
// на самом деле их нет в вашем файле компонента
// Так как функция connect вызывается "где-то там, где они доступны"
// вы имеете к ним доступ
let dispatch = () => console.log("dispatch")
let store = { user: { name: 'Mike', age: 15 }, data: [1,2,3] }
function connect(mapStateToProps, mapDispatchToProps) {
console.log(mapStateToProps(store))
}
function mapStateToProps(storeFromClosure) { // здесь оказывается глобальный store доступный из замыкания
return {
myData: storeFromClosure.data
}
}
connect(mapStateToProps, null)
<Select
name="form-field-name"
value="one"
options={options}
onChange={this.setUser} // тот самый onChange
/>
// текущий компонент
setUser(e) { this.props.setUser(e.target.value) }
// родитель
setUser(id) { this.props.actions.setUser(id) } // вызов redux action-creator
renderDistrict(item, key)
this.renderDistrict(item)
renderDistrict(item) {
return (
<tr key ={item.id} className="districts">
<td>{item.id}</td>
<td>{item.name}</td>
</tr>
)
}