Comments (9)
This works! Thanks for your help.
<Button
transparent
style={{ justifyContent: 'flex-start' }}
onPress={() => {
this.setState({ gender: 'female' }, instance.forceUpdate());
}}
>
<Icon
style={{ color: '#000' }}
name={this.state.gender === 'female' ? 'ios-radio-button-on' : 'ios-radio-button-off'}
/>
<Text style={{ color: '#000' }}>Female</Text>
</Button>
from react-native-stager.
instance.refresh
is a local API, that only re-evaluates the continue
prop. to re-update the whole children content, use context.notify
, it forces re-rendering on the Stager
on the current stage
from react-native-stager.
from react-native-stager.
when the stage is first entered, it always render everything you have in your local state (in your parent component), so you wouldn't need to call context.notify
in this case. the this.state
inside the stage children is more of a redux this.props
than to plain this.state
, because it's content is not bound to the parent state cycle
the reason for that is to render only parts that need to be rendered. react-native-router-flux for example usually mount all scenes and you have to manually reset the state depending on your current app state, and sometimes that's a real pain
from react-native-stager.
I still cannot get the gender to show up in <Text>{this.state.gender}</Text>
after I click a button.
<Stage
key="step 3"
loaded={(cb) => {
this.setState({ canContinue: true }, cb);
console.log('step 3 loaded', this.state);
}}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 12,
color: '#6B7580',
letterSpacing: 0,
lineHeight: 16,
}}>Step 3/5</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>What's your biological gender?</Text>
<Text style={{
top: 30,
left: 10,
fontSize: 14,
letterSpacing: 0,
lineHeight: 16,
}}>This ensures that you're given relevant info when searching medications.</Text>
<View style={{ top: 40 }}>
<Text>{this.state.gender}</Text>
<Button
transparent
style={{ justifyContent: 'flex-start' }}
onPress={() => this.setState({ gender: 'female' }, context.notify)}
>
<Icon
style={{ color: '#000' }}
name={this.state.gender === 'female' ? 'ios-radio-button-on' : 'ios-radio-button-off'}
/>
<Text style={{ color: '#000' }}>Female</Text>
</Button>
<Button
transparent
style={{ justifyContent: 'flex-start' }}
onPress={() => this.setState({ gender: 'male' }, context.notify)}
>
<Icon
style={{ color: '#000' }}
name={this.state.gender === 'male' ? 'ios-radio-button-on' : 'ios-radio-button-off'}
/>
<Text style={{ color: '#000' }}>Male</Text>
</Button>
<Button
transparent
style={{ justifyContent: 'flex-start' }}
onPress={() => this.setState({ gender: 'other' }, context.notify)}
>
<Icon
style={{ color: '#000' }}
name={this.state.gender === 'other' ? 'ios-radio-button-on' : 'ios-radio-button-off'}
/>
<Text style={{ color: '#000' }}>I'd rather not say</Text>
</Button>
</View>
</View>
)}
</Stage>
from react-native-stager.
Also, if I take the firstname/lastname form and place it above the stager, the text input works, but otherwise does not.
import React, { Component } from 'react';
import {
Header,
Container,
Content,
Button,
Icon,
Text,
Form,
Item,
Input,
Label,
Left,
Right,
View,
Toast,
} from 'native-base';
import Stager, { Stage, StageProgress, StageButtons } from 'react-native-stager';
import PinInput from 'react-native-pin-input';
import Modal from 'react-native-modal';
import styles from './styles';
export default class NewAccount extends Component {
constructor(props) {
super(props);
this.state = {
firstName: '',
lastName: '',
dobMonth: '',
dobDay: '',
dobYear: '',
gender: '',
pin: '',
canContinue: false,
showModal: false,
};
this.checkName = this.checkName.bind(this);
this.checkDOB = this.checkDOB.bind(this);
this.checkEmail = this.checkEmail.bind(this);
}
checkName() {
console.log('checkName', this.state.firstName, this.state.lastName);
this.setState({ canContinue: this.state.firstName !== '' && this.state.lastName !== '' });
}
checkDOB() {
console.log('checkDOB', this.state.dobMonth, this.state.dobDay, this.state.dobYear);
this.setState({
canContinue: this.state.dobMonth.length === 2 &&
this.state.dobDay.length === 2 &&
this.state.dobYear.length === 2
});
}
checkEmail() {
console.log('checkEmail', this.state.email);
this.setState({ canContinue: this.state.email !== '' });
}
render() {
return (
<Container style={styles.container}>
<Content>
<Header style={styles.header}>
<Left>
<Button
transparent
onPress={() => this.props.navigation.goBack()}
>
<Icon name="ios-arrow-round-back" />
</Button>
</Left>
</Header>
<Form style={{ top: 30 }}>
<Item stackedLabel>
<Label>First name</Label>
<Input
ref={(input) => { this.firstName = input; }}
value={this.state.firstName}
autoCorrect={false}
returnKeyType="next"
onChangeText={(text) => {
this.setState({ firstName: text });
}}
onSubmitEditing={() => {
this.lastName._root.focus();
this.checkName();
}}
onBlur={() => {
this.checkName();
}}
/>
</Item>
<Item stackedLabel>
<Label>Last name</Label>
<Input
ref={(input) => { this.lastName = input; }}
value={this.state.lastName}
autoCorrect={false}
returnKeyType="done"
onChangeText={(text) => {
this.setState({ lastName: text });
}}
onSubmitEditing={() => {
this.checkName();
}}
onBlur={() => {
this.checkName();
}}
/>
</Item>
</Form>
<Stager
onChange={(stage, direction) => {
// stage == step 1 || step 2
// direction = 1 = next | -1 = prev | 0 = reset / initial
}}
>
<StageProgress>
{() => (
<View key="progress" />
)}
</StageProgress>
<Stage
key="step 1"
loaded={(cb) => {
this.setState({ canContinue: false }, cb);
console.log('step 1 loaded', this.state);
}}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 12,
color: '#6B7580',
letterSpacing: 0,
lineHeight: 16,
}}>Step 1/5</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>What's Your Name?</Text>
<Form style={{ top: 30 }}>
<Item stackedLabel>
<Label>First name</Label>
<Input
ref={(input) => { this.firstName = input; }}
value={this.state.firstName}
autoCorrect={false}
returnKeyType="next"
onChangeText={(text) => {
this.setState({ firstName: text }, context.notify);
}}
onSubmitEditing={() => {
this.lastName._root.focus();
this.checkName();
}}
onBlur={() => {
this.checkName();
}}
/>
</Item>
<Item stackedLabel>
<Label>Last name</Label>
<Input
ref={(input) => { this.lastName = input; }}
value={this.state.firstName}
autoCorrect={false}
returnKeyType="done"
onChangeText={(text) => {
this.setState({ lastName: text }, context.notify);
}}
onSubmitEditing={() => {
this.checkName();
}}
onBlur={() => {
this.checkName();
}}
/>
</Item>
</Form>
</View>
)}
</Stage>
<Stage
key="step 2"
loaded={(cb) => {
this.setState({ canContinue: false }, cb);
console.log('step 2 loaded', this.state);
}}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 12,
color: '#6B7580',
letterSpacing: 0,
lineHeight: 16,
}}>Step 2/5</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>What's your date of birth?</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 14,
letterSpacing: 0,
lineHeight: 16,
}}>We'll use this to make sure you get the right medicine for your age.</Text>
<Form style={{ top: 30, flexDirection: 'row', flex: 1 }}>
<Item stackedLabel style={{ flex: 1 }}>
<Label>Month</Label>
<Input
ref={(input) => { this.dobMonth = input; }}
autoCorrect={false}
autoCapitalize="characters"
keyboardType="numeric"
returnKeyType="next"
maxLength={2}
onChangeText={(text) => {
this.setState({ dobMonth: text });
// if (text.length === 2) {
// this.dobDay.focus();
// }
}}
onSubmitEditing={() => {
this.dobDay.focus();
this.checkDOB();
}}
onBlur={() => {
this.checkDOB();
}}
/>
</Item>
<Item stackedLabel style={{ flex: 1 }}>
<Label>Day</Label>
<Input
ref={(input) => { this.dobDay = input; }}
autoCorrect={false}
autoCapitalize="characters"
keyboardType="numeric"
returnKeyType="next"
maxLength={2}
onChangeText={(text) => {
this.setState({ dobDay: text });
// if (text.length === 2) {
// this.dobYear.focus();
// }
}}
onSubmitEditing={() => {
this.dobYear.focus();
this.checkDOB();
}}
onBlur={() => {
this.checkDOB();
}}
/>
</Item>
<Item stackedLabel style={{ flex: 1 }}>
<Label>Year</Label>
<Input
ref={(input) => { this.dobYear = input; }}
autoCorrect={false}
autoCapitalize="characters"
keyboardType="numeric"
maxLength={2}
returnKeyType="done"
onChangeText={(text) => {
this.setState({ dobYear: text });
}}
onSubmitEditing={() => {
this.checkDOB();
}}
onBlur={() => {
this.checkDOB();
}}
/>
</Item>
<View style={{ flex: 1 }} />
</Form>
</View>
)}
</Stage>
<Stage
key="step 3"
loaded={(cb) => {
this.setState({ canContinue: true }, cb);
console.log('step 3 loaded', this.state);
}}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 12,
color: '#6B7580',
letterSpacing: 0,
lineHeight: 16,
}}>Step 3/5</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>What's your biological gender?</Text>
<Text style={{
top: 30,
left: 10,
fontSize: 14,
letterSpacing: 0,
lineHeight: 16,
}}>This ensures that you're given relevant info when searching medications.</Text>
<View style={{ top: 40 }}>
<Text>{this.state.gender}</Text>
<Button
transparent
style={{ justifyContent: 'flex-start' }}
onPress={() => {
this.setState({ gender: 'female' }, context.notify);
}}
>
<Icon
style={{ color: '#000' }}
name={this.state.gender === 'female' ? 'ios-radio-button-on' : 'ios-radio-button-off'}
/>
<Text style={{ color: '#000' }}>Female</Text>
</Button>
<Button
transparent
style={{ justifyContent: 'flex-start' }}
onPress={() => this.setState({ gender: 'male' })}
>
<Icon
style={{ color: '#000' }}
name={this.state.gender === 'male' ? 'ios-radio-button-on' : 'ios-radio-button-off'}
/>
<Text style={{ color: '#000' }}>Male</Text>
</Button>
<Button
transparent
style={{ justifyContent: 'flex-start' }}
onPress={() => this.setState({ gender: 'other' })}
>
<Icon
style={{ color: '#000' }}
name={this.state.gender === 'other' ? 'ios-radio-button-on' : 'ios-radio-button-off'}
/>
<Text style={{ color: '#000' }}>I'd rather not say</Text>
</Button>
</View>
</View>
)}
</Stage>
<Stage
key="step 4"
loaded={(cb) => {
this.setState({ canContinue: false }, cb);
console.log('step 4 loaded', this.state);
}}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 12,
color: '#6B7580',
letterSpacing: 0,
lineHeight: 16,
}}>Step 4/5</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>What's your email?</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 14,
letterSpacing: 0,
lineHeight: 16,
}}>No spam ever. We promise.</Text>
<Form style={{ top: 20 }}>
<Item stackedLabel>
<Label>Email</Label>
<Input
ref={(input) => { this.email = input; }}
autoCorrect={false}
returnKeyType="done"
autoCapitalize="none"
keyboardType="email-address"
onChangeText={(text) => {
this.setState({ email: text });
}}
onSubmitEditing={() => {
this.checkEmail();
}}
onBlur={() => {
this.checkEmail();
}}
/>
</Item>
</Form>
</View>
)}
</Stage>
<Stage
key="step 5"
loaded={cb => this.setState({ canContinue: false }, cb)}
continue={() => this.state.canContinue}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 12,
color: '#6B7580',
letterSpacing: 0,
lineHeight: 16,
}}>Step 5/5</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>Create a pin.</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 14,
letterSpacing: 0,
lineHeight: 16,
}}>You'll use this periodically to log in.</Text>
<Form style={{ top: 40, height: 100 }}>
<PinInput
text=""
pinLength={4}
pinItemStyle={{ width: 50, height: 50 }}
pinItemProps={{ keyboardType: 'number-pad' }}
onPinCompleted={(pin) => {
this.setState({ pin, canContinue: true });
}}
containerStyle={{ backgroundColor: 'transparent' }}
containerPinStyle={{
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
marginTop: 20,
}}
/>
</Form>
</View>
)}
</Stage>
<Stage
key="step 6"
loaded={cb => this.setState({ canContinue: false }, cb)}
continue={() => this.state.canContinue}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 12,
color: '#6B7580',
letterSpacing: 0,
lineHeight: 16,
}}>Step 5/5</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>Retype your pin.</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 14,
letterSpacing: 0,
lineHeight: 16,
}}>You'll use this periodically to log in.</Text>
<Form style={{ top: 40, height: 100 }}>
<PinInput
text=""
pinLength={4}
pinItemStyle={{ width: 50, height: 50 }}
pinItemProps={{ keyboardType: 'number-pad' }}
onPinCompleted={(pin) => {
if (pin === this.state.pin) {
this.setState({ pin, canContinue: true });
} else {
alert('Incorrect pin.');
}
}}
containerStyle={{ backgroundColor: 'transparent' }}
containerPinStyle={{
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
marginTop: 20,
}}
/>
</Form>
</View>
)}
</Stage>
<Stage
key="step 7"
loaded={cb => this.setState({ canContinue: false }, cb)}
continue={() => this.state.canContinue}
>
{({ instance, context }) => (
<View style={{ padding: 10 }}>
<Text style={{
top: 20,
left: 10,
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>Enable Touch ID?</Text>
<Text style={{
top: 20,
left: 10,
fontSize: 14,
letterSpacing: 0,
lineHeight: 16,
}}>Log in faster & more securely.</Text>
<Form style={{ top: 40, height: 100 }}>
<Button
rounded
block
onPress={() => {
Toast.show({
text: 'Touch ID Enabled!',
position: 'bottom',
buttonText: 'Awesome!',
});
this.setState({ showModal: true });
}}
>
<Icon name="md-finger-print" />
<Text style={{ color: '#fff' }}>Enable</Text>
</Button>
<Button
transparent
block
onPress={() => {
this.setState({ showModal: true });
}}
>
<Text style={{ color: '#000' }}>Skip for now</Text>
</Button>
</Form>
</View>
)}
</Stage>
<StageButtons>
{({ context }) => (
<View style={{ top: 30, flexDirection: 'row' }}>
{context.has('prev') &&
<Button transparent onPress={context.prev}>
<Icon name="ios-arrow-dropleft-circle" style={{ fontSize: 50, color: '#000' }} />
</Button>
}
{context.has('next') && this.state.canContinue &&
<Button transparent onPress={context.next} style={{ flex: 1, justifyContent: 'flex-end' }}>
<Icon name="ios-arrow-dropright-circle" style={{ fontSize: 50, color: '#000' }} />
</Button>
}
{context.has('next') && !this.state.canContinue &&
<Button transparent style={{ flex: 1, justifyContent: 'flex-end' }}>
<Icon name="ios-arrow-dropright-circle" style={{ fontSize: 50, color: '#ddd' }} />
</Button>
}
</View>
)}
</StageButtons>
</Stager>
<Modal
isVisible={this.state.showModal}
style={{
justifyContent: 'flex-end',
margin: 0,
}}
>
<View
style={{
backgroundColor: 'white',
padding: 22,
justifyContent: 'center',
alignItems: 'center',
borderRadius: 4,
borderColor: 'rgba(0, 0, 0, 0.1)',
}}
>
<Text style={{
fontSize: 29,
color: '#202326',
letterSpacing: -0.1,
lineHeight: 36,
}}>Before we get started, please read through our disclaimer.</Text>
<Button
transparent
style={{
top: 20,
left: 10,
}}
>
<Icon name="ios-mail" style={{ color: '#ccc' }} />
<Text style={{ color: '#ccc' }}>Email this to me</Text>
</Button>
<Text style={{
top: 20,
left: 10,
}}>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam justo est, suscipit a lobortis vitae, aliquet eu est. Donec eu dolor pretium, fringilla diam quis, hendrerit justo. Quisque dictum gravida egestas. In tristique sem sit amet ultricies porta. Sed molestie lorem ligula. Integer tortor eros, aliquet ut justo ac, blandit accumsan dui. Aliquam tempus sollicitudin massa tincidunt pretium. Nullam nec feugiat ante. Vestibulum posuere nibh eget sollicitudin consectetur. Curabitur ac finibus ligula. In placerat, ex non dictum aliquam, justo sem dignissim quam, at pretium felis erat vitae nibh.</Text>
<Button
style={{
marginTop: 20,
}}
rounded
block
onPress={() => {
this.setState({ showModal: false });
this.props.navigation.navigate('Drawer');
}}
>
<Text style={{ color: '#fff' }}>I agree</Text>
</Button>
<Button
style={{
paddingTop: 20,
}}
transparent
block
onPress={() => this.setState({ showModal: false })}
>
<Text style={{ color: '#000' }}>Cancel</Text>
</Button>
</View>
</Modal>
</Content>
</Container>
);
}
}
As you can see from the screenshot, the top form fields is updating, but the stage form fields are not even though they are tied to the same state.
from react-native-stager.
silly question, have you tried inspecting the element tree with React Native Debugger and see if the Text is in view? more than once I had "out of view" elements that had no height but was actually filled with content (which I don't know the cause for that, usually when messing with flex
style)
from react-native-stager.
My dependencies are:
"dependencies": {
"expo": "^20.0.0",
"immutable": "^3.8.1",
"native-base": "2.3.2",
"react": "16.0.0-alpha.12",
"react-native": "https://github.com/expo/react-native/archive/sdk-20.0.0.tar.gz",
"react-native-autofocus": "0.0.6",
"react-native-easy-grid": "^0.1.15",
"react-native-modal": "^3.1.0",
"react-native-pin-code": "0.0.2",
"react-native-pin-input": "^1.2.0",
"react-native-stager": "^0.2.3",
"react-native-svg": "^5.4.1",
"react-native-svg-image": "^2.0.0",
"react-native-svg-uri": "^1.2.1",
"react-native-touch-id": "^3.1.0",
"react-native-vector-icons": "^4.3.0",
"react-navigation": "1.0.0-beta.11",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0"
},
from react-native-stager.
the only thing I see different from the other stages is that it's placed outside a component that doesn't have it's own internal state (aka de <Text>
), the other's have their own context, so it looks like a bug from this component. it won't try to re-render when stateless components change. for the time being, can you create a quick stateless component outside your class (for the gender), and use it? like:
const Gender = ({ gender }) => (<Text>{gender}</Text>)
// then use it
<Gender gender={this.state.gender} />
EDIT: it's actually a bug because of shouldComponentUpdate
return false
and never re-evaluating the children
function, it never updates stateless components, I'll fix this. I'll check if performance is impacted by the change as well. for a work around, you can try using instance.forceUpdate()
from react-native-stager.
Related Issues (10)
- How to use StageProgress and StageButtons ? HOT 2
- Consider write the documentation for instance.refresh, instances.forceUpdate& context.notify HOT 1
- Screenshots or Demo Video HOT 1
- StageButtons HOT 7
- Go to specific stage HOT 2
- Unable to resolve module HOT 7
- Override stager/stage styles HOT 4
- Conditional render of stage HOT 15
- StageButton onPress called twice then three times HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-native-stager.