How redux form passing props from HOC to Input Element - react-native

I am using native-base (a material ui library for react-native) with redux form for managing state of form using redux. I am confused with the following bit of code. In below code it is taking number of argument and pass it to Input Tag with triple dot. but i could not identify what is this and from where it is getting rest of properties and how i can apply custom props.
renderInput({ input, label, meta: { touched, error, warning } }){
console.log(input)
var hasError= false;
if(error !== undefined){
hasError= true;
}
return(
<Item error= {hasError}>
<Input {...input}
/>
{hasError ? <Text>{error}</Text> : <Text />}
</Item>
)
}
Below is the render method which is calling above function from Higher Order Field Component of redux form.
render(){
const { handleSubmit, reset } = this.props;
if (!this.state.isReady) {
return <Expo.AppLoading />;
}
return (
<Container>
<Header>
<Body>
<Title>Redux Form</Title>
</Body>
</Header>
<Content padder>
<Field name="email" component={this.renderInput} model="sudhakar" type="text" placeholder="Username" />
<Field name="name" component={this.renderInput} type="password" placeholder="Password" />
<Input name="age" type="text" ref="_age" />
<Button block primary onPress= {this.handleLogin}
style={{marginHorizontal:10,backgroundColor:"#00adef", marginTop:50}}
>
<Text>Submit</Text>
</Button>
</Content>
</Container>
)
}
You can find complete code here

I'm not allowed to post comment because my reputation is below 50.
The triple dot is called spread operator, I think this is the key to understanding what you're confused about. when I first saw this syntax I had the same confusion. try reading the link above plus this and I think you should be able to figure out ur problem :)

Related

React Native: Element Type is invalid Exspecting a String

import {CITYIMG} from '../assets/index';
export default class Login extends Component {
render() {
return (
<Container>
<Image source = {CITYIMG}/>
<Card style={styles.card}>
<Text>
Sign In
</Text>
<Item rounded>
<Input placeholder='Username'/>
</Item>
<Item rounded>
<Input placeholder='Password'/>
</Item>
<Button hasText transparent>
<Text>Forgot Password</Text>
</Button>
<Button rounded>
<Text>Login</Text>
</Button>
<Button rounded>
<Text>Sign Up</Text>
</Button>
</Card>
</Container>
);
}
}
I am exporting images in another folder and get the error:
Expected String or a class function but got undefined . You likely forgot to export your component from the file its defined in.
export const CITYIMG = require('./cityimg.jpg');
for having static images you need to have source={require("../Path/To/picture.extention")}
and you need to require them when you want to use it in the same file(not by exporting and importing)

get the roles previously linked to users

i have a problem i cannot solve, and i think im following the documentation to the letter.
I want to obtain the assigned roles when im editing the user, for example if exist a user "Daniel", which has "Administrator" and "Editor" roles. When im editing that user i would like to obtain those assigned roles.
my code is:
export const UserEdit = props => (
<Edit title={<RoleTitle />} {...props}>
<SimpleForm validate={validateUserEdition}>
<TextInput source="name" />
<TextInput source="email" type="email" />
<TextInput source="password" type="password" />
<ReferenceInput label="Role" source="role" reference="role">
<AutocompleteArrayInput source="id" {...props} />
</ReferenceInput>
</SimpleForm>
</Edit>
);
Add the endpoint format where check my API:
GET to /user/{user}/role
someone help me with this please?
Here's what the react-admin say:
You must add a for the reference resource - react-admin needs it to fetch the reference data.
So in your case, the <Admin/> component should at least have these:
<Admin dataProvider={myDataProvider}>
<Resource name="users" /> // endpoint that handles user records
<Resource name="roles" /> // endpoint that handles user ROLES records
</Admin>
Am not sure how you are using this endpoint /user/{user}/role but it clearly will not do what you want. Further reading here should help especially look at the notes added to the Reference* components.
I still cannot solve my problem, the resources that I have in my administrator are user and role, but I imagine that with those resources they are enough to have the relationship between the two.
Again, when I edit a user, I need to be able to view and edit the roles associated with it.
my code is the follow
export const UserEdit = props => (
<Edit title={<RoleTitle />} {...props}>
<SimpleForm validate={validateUserEdition}>
<TextInput source="name" />
<TextInput source="email" type="email" />
<TextInput source="password" type="password" />
<ReferenceInput label="Role" source="role" reference="role">
<AutocompleteArrayInput source="id" {...props} />
</ReferenceInput>
</SimpleForm>
</Edit>
);
in app.js
const App = ( ) => (
<Admin dashboard={ Dashboard } dataProvider={ dataProvider } authProvider={ authProvider }>
<Resource name="user" list={ UserList } create={ UserCreate } edit={ UserEdit } icon={ UserIcon }/>
<Resource name="role" list={ RoleList } create={ RoleCreate } edit={ RoleEdit } icon={ ContactsIcon }/>
</Admin>
);
Thank

React-native Input HOC for redux-form loses focus after type a symbol

I'm trying to use redux-form, but, as I read, I need HOC for Input field to replace onTextChange to onChange. I have:
import React from 'react';
import {Input} from 'native-base';
export default function InputField(props) {
const { input, ...inputProps } = props;
return (
<Input
{...inputProps}
onChangeText={input.onChange}
onBlur={input.onBlur}
onFocus={input.onFocus}
value={input.value}
/>
);
};
and use it in my form:
<Item style={{marginTop: 10, width: "100%"}}>
<Field name="login" component={(props) => {
return (
<InputField {...props} keyboardType="email-address" placeholder='E-mail' />
)
}}/>
</Item>
But every time I type key, the field loses focus. Some "experts" recommend use focus() function. But what if I edit text in the middle of it?
Any solutions? Or maybe native-base have compatible textfield component?
It is strange, but it works ))
function InputFieldEmail(props) {
return <InputField {...props} keyboardType="email-address" placeholder='E-mail' />;
}
and use it instead arrow functions
<Field name="login" component={InputFieldEmail}/>
I think it's strange )
You must provide the InputField component as a prop so that its value is constant or put it outside the Item component, when it is inside another, every time the state of the upper level is updated, the lower level is forced to return. to start.
If your Input is inside an Item you are probably using a FlatList and your goal is to put it in the header.
You can try something like this:
<View style={{marginTop: 10, width: "100%"}}>
<Field name="login" component={(props) => {
return (
<InputField {...props} keyboardType="email-address" placeholder='E-mail' />
)
}}/>
</View>
<FlatList
ListHeaderComponent={() => {
<Item>
</Item>
}}
/>
Remember to put the styles that were in Item in View.

Changing segment content onPress

I have segments and I want them to act as tabs. I tried using react-navigation onPress of each segment but it doesn't look nice.
I want the segments to stay fixed at the top and on clicking each one the content should change or call a specific component without reloading or noticing that the screen has changed.
<Segment>
<Button first>
<Text>Puppies</Text>
</Button>
<Button>
<Text>Kittens</Text>
</Button>
<Button last active>
<Text>Cubs</Text>
</Button>
</Segment>
<Content>
<Text>Awesome segment</Text>
</Content>
Segments can be customized as a react-navigation single screen separated into multiple components which can be rendered on demand.
Example
(Using native-base components)
state = {
activePage:1,
}
selectComponent = (activePage) => () => this.setState({activePage})
_renderComponent = () => {
if(this.state.activePage === 1)
return <Component1/> //... Your Component 1 to display
else
return <Component2/> //... Your Component 2 to display
}
render() {
return (
<Container>
<Header>
<Left />
<Body>
<Segment>
<Button active={this.state.activePage === 1}
onPress={this.selectComponent(1)}><Text>Component 1</Text></Button>
<Button active={this.state.activePage === 2}
onPress= {this.selectComponent(2)}><Text>Component 2</Text></Button>
</Segment>
</Body>
<Right/>
</Header>
<Content padder>
{this._renderComponent()}
</Content>
</Container>
)
}
You can customize it to add more components based on the conditions set above
Edit
Supposing you navigate to a particular screen that also contains Segment, the on some item button click you can do
this.props.navigation.navigate('OtherSegmentScreen', {activePage: this.state.activePage})
And on that page receive the props as
const {navigate} = this.props.navigation
const previousActiveSegment = navigate.getParams('activePage', '1') //... 1 is default value that you can set

Implementing Footer Tabs in Native React using Native Base

I am creating a native react application using native base for the UI (http://nativebase.io/docs/v2.0.0/components#footerTab). I am using the footerTabs component and my code is as follows
render() {
return (
<Container>
<Header backgroundColor="#ECEFF1">
<Button transparent>
<Icon name='ios-menu' style={{color: 'black'}}/>
</Button>
<Title style={{color:'black'}}>Header</Title>
</Header>
<Content>
<Profile/>
</Content>
<Footer backgroundColor="#212121">
<FooterTab>
<Button backgroundColor="#000" >
<Icon name="ios-person" size={30} color="#900"/>
<Text>Profile</Text>
</Button>
<Button>
<Icon name="ios-search"/>
<Text>Search</Text>
</Button>
<Button>
<Icon name="ios-camera"/>
<Text>Camera</Text>
</Button>
<Button>
<Icon name="ios-apps"/>
<Text>Apps</Text>
</Button>
<Button>
<Icon active name="ios-navigate"/>
<Text>Navigate</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
I have created different JS files for different functionalities such as Profiles,Search,Apps ect.. and have imported them as follows.
import Profile from './Profile';
How do I implement the onPress functionality on the buttons of the footer to change the component in the content tag depending on what was selected?
<Content>
<Profile/>
</Content>
For eg: If I pressed the search button I want the profile tag to be replaced with and similarly the same for the other buttons.
Here FooterTab from native base is not persist actual tab functionality like UITabBar in iOS, its only persist for design. What you need to do is, keep footer tag in all of your component with all four buttons and keep active accordingly. For changing view by selecting any button you need to replace current view by selected one using navigator like:
<Button onPress={()=> { this.props.navigator.replace({id:'component name'}) }}>
and in your navigator component you should define all required components in renderScene method on the basis of id value in route payload. If you want actual functionality as TabBar work then you can use this third party module react-native-tab-navigator. Thanks!
Instead of replacing the content, why don't you have each Button navigate to a new page?
Let's say you're on the Profile tab. You could do something like this:
import FooterWrapper from './FooterWrapper'
<Footer>
<FooterWrapper tab='profile' navigator={this.props.navigator} />
</Footer>
And then in your FooterWrapper (I just handled a case of two tabs):
constructor(props) {
super(props)
this.state = {
profileTab: this.props.tab === 'profile',
searchTab: this.props.tab === 'search',
}
}
navToProfilePage() {
this.props.navigator.push({
id: 'profile',
tab: 'profile',
})
}
navToSearchPage() {
this.props.navigator.push({
id: 'search',
tab: 'search',
})
}
render() {
return (
<FooterTab>
<Button active={this.state.profileTab} onPress={() => this.navToProfilePage()}>
Profile
<Icon name='ios-person' size={30} color='#900' />
</Button>
<Button active={this.state.searchTab} onPress={() => this.navToSearchPage()}>
Search
<Icon name='ios-search' />
</Button>
</FooterTab>
)
}
Ok so here is I how got it I used the renderContent method within the content tags to generate views depending on the state change when the button was clicked.
<Content>
{this._renderContent(this.state.selectedTab)}
</Content>
The selectedTab is a state variable whose state is set using this.setState in the onPress method. The renderContent has an if function that checks the selected tab and returns the appropriate view. I also tried the navigation approach but this seemed cleaner.
_renderContent = (Tab: string,) => {
if(this.state.selectedTab==="Profile"){
return (
<Profile/>
);
}
else if(this.state.selectedTab==="Search"){
}
}