Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit 5f6d4c2

Browse files
authored
Merge pull request #847 from andrewhl/docs/react-native
Improve React Native Form and Control implementations
2 parents 7c49bad + 1d4614a commit 5f6d4c2

File tree

2 files changed

+142
-2
lines changed

2 files changed

+142
-2
lines changed

docs/guides/react-native.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class App extends React.Component {
2424
export default App;
2525
```
2626

27+
<a name="native-controls"/>
2728
## Native `<Control>`
2829

2930
The following React Native iOS form controls are available:
@@ -36,6 +37,8 @@ The following React Native iOS form controls are available:
3637
- `<Control.Switch>`
3738
- `<Control.TextInput>`
3839

40+
See [below](#examples) for examples.
41+
3942
The `model` prop is required for these controls to work with React Redux Form.
4043

4144
For most controls, the original `onFocus` and `onBlur` props are mapped to:
@@ -81,3 +84,140 @@ By default, the `<Errors>` component will render:
8184
- and each error component as `<Text>`.
8285

8386
Of course, you can override this by specifying the component in the `wrapper={...}` and `component={...}` props of `<Errors />`.
87+
88+
<a name="examples"></a>
89+
## Control.Picker with Picker.Items
90+
Simply import `Picker` from `react-native`, and pass the `Picker.Item`s in as children.
91+
92+
```jsx
93+
import React, { Picker } from 'react-native';
94+
import { Form, Control } from 'react-redux-form/native';
95+
96+
class Form extends React.Component {
97+
render() {
98+
return (
99+
<Form model="user">
100+
<Control.Picker model=".gender">
101+
<Picker.Item label="Male" value="male" />
102+
<Picker.Item label="Female" value="female" />
103+
<Picker.Item label="Other" value="other" />
104+
</Control.Picker>
105+
</Form>
106+
);
107+
}
108+
}
109+
110+
export default Form;
111+
```
112+
113+
## Using Custom Form Components
114+
To use a third-party form control component select the appropriate `Control` type (e.g., `Control.TextInput`) and override the `component` prop with your custom component. The custom component must resolve to one of the supported React Native form control types. See the supported types [here](#native-controls).
115+
116+
```jsx
117+
import React from 'react-native';
118+
import { Form, Control } from 'react-redux-form/native';
119+
import { Input } from 'native-base';
120+
121+
class Form extends React.Component {
122+
render() {
123+
return (
124+
<Form model="user">
125+
<Control.TextInput
126+
placeholder="Last Name"
127+
model=".last_name"
128+
component={Input}
129+
/>
130+
</Form>
131+
);
132+
}
133+
}
134+
135+
export default Form;
136+
```
137+
138+
## Using Non-Supported Custom Form Components
139+
If you are using a non-standard form control that does not implement one of the standard React Native iOS form controls ([listed here](#native-controls)), you will need to manually redefine `mapProps` for the control's event handlers.
140+
141+
Below is an example of a custom `Picker` component with `mapProps` redefined.
142+
143+
```jsx
144+
import React from 'react-native';
145+
import { Form, Control } from 'react-redux-form/native';
146+
import { Picker } from 'custom-form-library';
147+
148+
class Form extends React.Component {
149+
render() {
150+
return (
151+
<Form model="user">
152+
<Control
153+
component={Picker}
154+
mapProps={{
155+
onResponderGrant: ({ onFocus }) => onFocus,
156+
onResponderRelease: ({ onBlur }) => onBlur,
157+
selectedValue: ({ modelValue }) => modelValue,
158+
onValueChange: ({ onChange }) => onChange,
159+
onChange: undefined,
160+
}}
161+
model=".relationship"
162+
>
163+
<Picker.Item label="Select relationship" value="select" />
164+
<Picker.Item label="Spouse" value="spouse" />
165+
<Picker.Item label="Child" value="child" />
166+
<Picker.Item label="Sibling" value="sibling" />
167+
<Picker.Item label="Parent" value="parent" />
168+
<Picker.Item label="Grandparent" value="grandparent" />
169+
<Picker.Item label="Other" value="other" />
170+
</Control>
171+
</Form>
172+
);
173+
}
174+
}
175+
176+
export default Form;
177+
```
178+
179+
Below is an example of a custom `Input` component. Note that an additional method is defined to handle coercing inputs to string format.
180+
181+
```jsx
182+
import React from 'react-native';
183+
import { Form, Control } from 'react-redux-form/native';
184+
import { Input } from 'custom-form-library';
185+
186+
function getTextValue(value) {
187+
if (typeof value === 'string' || typeof value === 'number') {
188+
return `${value}`;
189+
}
190+
191+
return '';
192+
}
193+
194+
class Form extends React.Component {
195+
render() {
196+
return (
197+
<Form model="user">
198+
<Control
199+
placeholder="First Name"
200+
model=".first_name"
201+
component={Input}
202+
validators={{
203+
required: val => val && val.length,
204+
}}
205+
mapProps={{
206+
onResponderGrant: ({ onFocus }) => onFocus,
207+
value: _props => ((! _props.defaultValue &&
208+
! _props.hasOwnProperty('value'))
209+
? getTextValue(_props.viewValue)
210+
: _props.value),
211+
onChangeText: ({ onChange }) => onChange,
212+
onChange: undefined,
213+
onBlur: ({ onBlur, viewValue }) => () => onBlur(viewValue),
214+
onFocus: ({ onFocus }) => onFocus,
215+
}}
216+
/>
217+
</Form>
218+
);
219+
}
220+
}
221+
222+
export default Form;
223+
```

src/native.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Control.Switch = (props) => (
7777
mapProps={{
7878
onResponderGrant: ({ onFocus }) => onFocus,
7979
onResponderRelease: ({ onBlur }) => onBlur,
80-
value: ({ modelValue }) => !!modelValue,
80+
value: ({ modelValue }) => ! ! modelValue,
8181
onValueChange: ({ onChange }) => onChange,
8282
onChange: noop,
8383
...props.mapProps,
@@ -91,7 +91,7 @@ Control.TextInput = (props) => (
9191
component={TextInput}
9292
mapProps={{
9393
onResponderGrant: ({ onFocus }) => onFocus,
94-
value: (_props) => ((!_props.defaultValue && !_props.hasOwnProperty('value'))
94+
value: (_props) => ((! _props.defaultValue && ! _props.hasOwnProperty('value'))
9595
? getTextValue(_props.viewValue)
9696
: _props.value),
9797
onChangeText: ({ onChange }) => onChange,

0 commit comments

Comments
 (0)