I am using react-redux for changing the state in my app.In my router page how can I route based on conditions.ie,If the user logged status is true then if i go to the login component it must redirect to the home component and the user logged status is false,if i go to the home component it must redirect to the login component.
routes.js
const routes=() => (
<Router>
<div>
<Header />
<Route exact path="/" render={ props => <div><FirstConnectedComponent /><SecondConnectedComponent /></div>} />
<Route path="/login" component={ requireAuth(Login) } />
<Route path="/register" component={ UserReg } />
<Route path="/home" component={ Home } />
<Footer />
</div>
</Router>
)
export default routes;
How about creating a new route component called PrivateRoute
PrivateRoute.js
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
export const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
localStorage.getItem('authenticated')
? <Component {...props} />
: <Redirect to={{ pathname: '/login', state: { from: props.location } }} />
)} />
)
index.js
First import it then use -
<PrivateRoute path="/" component={MyComponent} />
You can add a function call :
onEnter={this.requireAuth.bind(this)}
And the function could be something like this :
requireAuth(nextState, replace) {
if (this.user === undefined || this.user === null) {
replace('/login');
}
}
Related
My React Native 0.61.5 uses react-navigation 5.1. Here is the root navigation code:
const BTab = createBottomTabNavigator();
const Stack = createStackNavigator();
export default function App() {
//const Appscreen = () => (<AppScreen data={data}/>);
return (
<NavigationContainer>
<Stack.Navigator InitialRouteName="Splash">
<Stack.Screen name="Splash" component={SplashScreen}}/>
<Stack.Screen name="App" component={AppScreen} } />
</Stack.Navigator>
</NavigationContainer>
);
}
The component AppScreen return a stack like this:
return (
<NavigationContainer independent={true}>
<BTab.Navigator>
<BTab.Screen name="Event" component={Eventstack} />
<BTab.Screen name="Group" component={Groupstack} />
<BTab.Screen name="Contact" component={Contactstack} />
</BTab.Navigator>
</NavigationContainer>
);
I notice that on the screen there are double header:
How can I remove the App header and only keep the Group?
add with the screen that you want to hide the header.
options= {{
headerShown: false
}}
For further reading, kindly have a look at https://reactnavigation.org/docs/stack-navigator/#headershown
I've reduced this to a very simple case for ease of discussion. I have a simple create form with 1 field and 1 button. I would like the button to set the value of the TextInput to "Hello" without submitting the form. How is this possible in admin on rest? eg:
export const TestCreate = (props) => (
<Create title={<TestTitle />} {...props}>
<SimpleForm>
<TextInput source="title" />
<TitleSetterButton />
</SimpleForm>
</Create>
);
Been struggling with this for a while - it should be simple so hopefully there's an easy answer.
I was able to setup a Sample form using their example application
// in src/posts.js
import React from 'react';
import { List, Edit, Create, Datagrid, ReferenceField, TextField, EditButton, DisabledInput, LongTextInput, ReferenceInput, required, SelectInput, SimpleForm, TextInput } from 'admin-on-rest';
import FlatButton from 'material-ui/FlatButton';
export const PostList = (props) => (
<List {...props}>
<Datagrid>
<TextField source="id" />
<ReferenceField label="User" source="userId" reference="users">
<TextField source="name" />
</ReferenceField>
<TextField source="title" />
<TextField source="body" />
<EditButton />
</Datagrid>
</List>
);
const PostTitle = ({ record }) => {
return <span>Post {record ? `"${record.title}"` : ''}</span>;
};
export class Testing extends React.Component {
render() {
return <input type="text" />
}
}
export class PostCreate extends React.Component {
componentDidMount() {
console.log(this)
}
constructor(props) {
super(props);
this.handleCustomClick = this.handleCustomClick.bind(this);
// this.fieldOptions = this.fieldOptions.bind(this);
}
handleCustomClick() {
this.fields.title.handleInputBlur("tarun lalwani");
this.fields.body.handleInputBlur("this is how you change it!");
}
render () {
let refOptions = {ref: (e) => {
if (e && e.constructor && e.props && e.props.name) {
this.fields = this.fields || {};
this.fields[e.props.name] = e;
}
}}
return (
<Edit title={<PostTitle />} {...this.props}>
<SimpleForm>
<DisabledInput source="id" />
<ReferenceInput label="User" source="userId" reference="users" validate={required}>
<SelectInput optionText="name" />
</ReferenceInput>
<TextInput source="title" options={refOptions}/>
<LongTextInput source="body" options={refOptions}/>
<FlatButton primary label="Set Value" onClick={this.handleCustomClick} />
</SimpleForm>
</Edit>
);
}
}
Before click of the button
After clicking Set Value
And then after clicking Save you can see the actual changed values get posted
We are integrating AOR(version 1.2.3) with existing Application.
we are trying to provide Edit Feature in that when we give
<---Field> Components its working fine
also able to see SAVE button
but
when it <---Input> Components
no SAVE button is visible and Component does take inputs.
Code when
Field Components are used
import React, { Component } from 'react';
import {
Components
} from 'admin-on-rest';
const CustomerEdit = (props) => (
<Edit {...this.props}>
<TabbedForm>
<FormTab label="Profile">
<TextField source="firstName" />
<TextField source="middleName" />
<TextField source="lastName" />
</FormTab>
<FormTab label="Address">
<ReferenceManyField addLabel={false} reference="CustomerAddresses" target="customerProfileId">
<Datagrid>
<EditButton/>
<TextField source="id" />
<TextField source="line1" />
<TextField source="pinCode" />
</Datagrid>
</ReferenceManyField>
</FormTab>
</TabbedForm>
</Edit>
);
export default CustomerEdit;
Code when
Input
Components are used
import React, { Component } from 'react';
import {
Components
} from 'admin-on-rest';
const CustomerEdit = (props) => (
<Edit {...this.props}>
<TabbedForm>
<FormTab label="Profile">
<TextInput source="firstName" />
<TextInput source="middleName" />
<TextInput source="lastName" />
</FormTab>
<FormTab label="Address">
<ReferenceManyField addLabel={false} reference="CustomerAddresses" target="customerProfileId">
<Datagrid>
<EditButton/>
<TextInput source="id" />
<TextInput source="line1" />
<TextInput source="pinCode" />
</Datagrid>
</ReferenceManyField>
</FormTab>
</TabbedForm>
</Edit>
);
export default CustomerEdit;
This is App.js
import React from 'react';
import PropTypes from 'prop-types';
// redux, react-router, redux-form, saga, and material-ui
// form the 'kernel' on which admin-on-rest runs
import { combineReducers, createStore, compose, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import createHistory from 'history/createHashHistory'
import { Switch, Route } from 'react-router-dom'
import { ConnectedRouter, routerReducer, routerMiddleware } from 'react-router-redux';
import { reducer as formReducer } from 'redux-form';
import createSagaMiddleware from 'redux-saga';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
// prebuilt admin-on-rest features
import {
adminReducer,
localeReducer,
crudSaga,
TranslationProvider,
} from 'admin-on-rest';
import restClient from './restClient';
import GenericList from './ui/List';
import CustomerEdit from './ui/views/customer/customerEdit';
const reducer = combineReducers({
admin: adminReducer([{ name: 'CustomerProfiles' },
{ name: 'CustomerAddresses' }]),
locale: localeReducer(),
form: formReducer,
routing: routerReducer,
});
const sagaMiddleware = createSagaMiddleware();
const history = createHistory();
const store = createStore(reducer, undefined, compose(
applyMiddleware(sagaMiddleware, routerMiddleware(history)),
window.devToolsExtension ? window.devToolsExtension() : f => f,
));
sagaMiddleware.run(crudSaga(restClient));
const App = () => (
<Provider store={store}>
<TranslationProvider messages={messages}>
<ConnectedRouter history={history}>
<MuiThemeProvider>
<Switch>
<Route exact path="/profile"
hasCreate render={
(routeProps) => <GenericList resource="CustomerProfiles" {...routeProps} />
} />
<Route exact path="/profile/:id"
hasEdit render={
(routeProps) => <CustomerEdit resource="CustomerProfiles" {...routeProps} />
} />
</Switch>
</MuiThemeProvider>
</ConnectedRouter>
</TranslationProvider>
</Provider>
);
export default App
This in case of Input Components
No Data from Backend for CustomerAddress and also no Save Button
This in Case of Field Component
when we use <---FIELD/> Component
Don't you have an error in the console about ReferenceManyInput ? This component does not exist.
I checked the documentation and we indeed included it in the Resources chapter. It will be fixed soon.
For referencing many other resources, you should use the ReferenceArrayInput. However, it does not support Datagrids. There are not components allowing you to edit related resources yet.
Currently whenever I try to link to a nested route that renders a new element, I get the too much recursion error. For obvious reasons it keeps rerendering this component. Where does one put a nested route so it doesnt get rendered over and over again?
redirectAddSurvey(){
this.props.addSurvey("Titel Survey", "Survey beschrijving"); this.props.history.push(`/survey/${this.props.match.params.action}`);
}
render() {
return (
<div id="newSurveyButton">
<RaisedButton containerElement={ <Link to={`${this.props.match.url}/new`} />} label="Add new Survey" onClick={() => this.redirectAddSurvey()}></RaisedButton>
<Route path={`${this.props.match.url}/:action`} render={props => <Survey title="Helloworld" desc="HelloDesc" {...props} />} />
</div>
);
}
}
// Get apps state and pass it as props to SurveyList
// > whenever state changes, the SurveyList will automatically re-render
function mapStateToProps(state) {
return {
surveys: state.surveys,
};
}
Updated:
render() {
return (
<div id="newSurveyButton">
<RaisedButton label="Add new Survey" onClick={() => this.redirectAddSurvey()}></RaisedButton>
<Link to={`${this.props.match.url}/new`} />
<Route path={`survey/:action`} render={props => <Survey title="Helloworld" desc="HelloDesc" {...props} />} />
</div>
);
}
I'm trying to use react-router with a server in Go.
I did some tests but I can not do what I want.
My react components :
var App = React.createClass({
render: function(){
return (
<div>
<h2>App</h2>
<li><Link to="/page1">Page 1</Link></li>
<li><Link to="/page2">Page 2</Link></li>
</div>
)
}
})
var Page1 = React.createClass({
render: function(){
return (
<div>
<h2>Page 1</h2>
<li><Link to="/page2">Page 2</Link></li>
</div>
)
}
})
var Page2 = React.createClass({
render: function(){
return (
<div>
<h2>Page 2</h2>
<li><Link to="/page1">Page 1</Link></li>
</div>
)
}
})
My react routing :
ReactDOM.render((<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="page1" component={Page1} />
<Route path="page2" component={Page2} />
</Route>
</Router>), document.getElementById('app'))
my go server :
func Render(c web.C, w http.ResponseWriter, r *http.Request) {
RenderHTMLPage(w, "index.html")
}
func main() {
goji.Get("/page1", Render)
goji.Get("/page2", Render)
goji.Get("/", Render)
goji.Serve()
}
My problem is when i click on Link in 'App' Component, for example :
<li><Link to="/page1">Page 1</Link></li>
url changes like that
http://localhost:8000/page1
But actual component is already App and not Page1, so url changes but not component.
And if i load directly url, i have the same result.
Does anyone help me ?
Thank's :)
This isn't a go question, but a react question, you need to render the App component's children in order for the other two components to display, a la this code snippet taken from the docs for React Router (https://github.com/reactjs/react-router/blob/master/docs/API.md#props-2):
const routes = (
<Route component={App}>
<Route path="groups" component={Groups} />
<Route path="users" component={Users} />
</Route>
)
class App extends React.Component {
render () {
return (
<div>
{/* this will be either <Users> or <Groups> */}
{this.props.children}
</div>
)
}
}