I'm implementing the react native swiper (https://github.com/leecade/react-native-swiper) in a project
class MainSwiper extends React.Component {
_onMomentumScrollEnd() {
// Edit some state of the SomeView here...
}
render() {
return (
<Swiper
onMomentumScrollEnd={this._onMomentumScrollEnd}>
<View>
<SomeView />
</View>
// More views here...
</Swiper>
);
}
}
AppRegistry.registerComponent('some_app', () => MainSwiper);
And I want the method _onMomentumScrollEnd() to change some state of the SomeView declared in the JSX.
Suppose SomeView is defined as:
class SomeView extends React.Component {
constructor(props) {
super(props);
this.state = {somestate = 'Hi!'};
}
render() {
return (
<Text>{this.state.somestate}</Text>
);
}
}
I realize I might be approaching this issue in the wrong way, but I don't know how it's done. How can somestate be changed from _onMomentumScrollEnd() (or any other MainSwiper method) and get the SomeView to re-render, i.e. how do I access the SomeViewelement from within a MainSwiper method?
You should pass state to the SomeView component by its props. So you could do
class MainSwiper extends React.Component {
_onMomentumScrollEnd() {
this.setState({somestate: A String})
}
render() {
return (
<Swiper
onMomentumScrollEnd={this._onMomentumScrollEnd}>
<View>
<SomeView somestate={this.state.somestate} />
</View>
// More views here...
</Swiper>
);
}
}
AppRegistry.registerComponent('some_app', () => MainSwiper);
And then in SomeView
class SomeView extends React.Component {
render() {
return (
<Text>{this.props.somestate}</Text>
);
}
}
Notice how the SomeView component became a stateless component by not keeping its own state. It's not mandatory but it's a good practice.
Related
I would like to get the value of the switch inside ToggleCampus from Map.js. How can I update the value of the state inside Map.js from ToggleCampus.js?
Map.js
export default class Map extends React.Component{
constructor(props) {
super(props);
this.state = { switchVal: true};
}
render(){
return (
<ToggleCampus switchVal = {this.state.switchVal} />
);
}
}
ToggleCampus.js
export default class ToggleCampus extends React.Component {
constructor(props){
super(props);
}
render() {
console.log(this.props.switchVal);
return(
<Switch
value={this.props.switchVal}
*(not sure how to use onChange here)*
/>
);
}
}
So basically what you have to do is pass the function as props to ToggleCampus to update the switchVal. Like suppose in ToggleCampus you want to change the value on button click, so check the below method:
Map.js
export default class Map extends React.Component{
constructor(props) {
super(props);
this.state = { switchVal: true};
}
changeSwitch = (value) => {
this.setState({switchVal:value});
}
render(){
return (
<ToggleCampus changeSwitch={this.changeSwitch} switchVal = {this.state.switchVal} /> // passed changeSwitch
);
}
}
and in togglecampus.js
export default class ToggleCampus extends React.Component {
constructor(props){
super(props);
}
render() {
console.log(this.props.switchVal);
return(
<>
<Switch
value={this.props.switchVal}
*(not sure how to use onChange here)*
/>
<Button title="click" onPress={() => this.props.changeSwitch(false)} /> // added this
</>
);
}
}
hope it helps.
I call a function that is in my Homepage class from my ProfileScreen class that is in the same .js file. I successfully did that, but in that function a setState is called, and when the function is called from the other class, the state doesn't change. How can I get this.state.user in HomePage to change from calling the onPressLogout function in the ProfileScreen class?
export default class HomePage extends Component<Props> {
state = {
email:'',
password:'',
firstname:'',
lastname:'',
user:true,
error: '',
}
onPressLogout(){
firebase = require('firebase');
firebase.auth().signOut()
.then(() => this.setState({
user:false
}))
.catch(() => this.setState({
error: 'Logout Failure',
}))
}
render(){
return <AppContainer>
</AppContainer>;
}
}
class ProfileScreen extends React.Component {
constructor(props) {
super(props);
Obj = new HomePage();
}
render() {
return (
...
<TouchableOpacity style={styles.button} onPress =
{()=>Obj.onPressLogout()}>
</TouchableOpacity>
...
}
}
const TabNavigator = createBottomTabNavigator({
Profile: ProfileScreen,
});
const AppContainer = createAppContainer(TabNavigator);
I get this warning when I run the code and the this.state.user doesn't change:
Warning: Can't call "setState" on a component that is not yet mentioned.
You should pass the function of the parent element into the child element as a prop. Then, you can call it in the child to manipulate the state of the parent class.
Here is an example,
class ChangeButton extends React.Component{
render(){
return (
<Button title="Change" onPress={this.props.updateMainState}/>
)
}
}
export default class App extends React.Component {
state = {
name: 'Fatih'
}
changeName = ()=> {
this.setState({
name: 'Faruk'
})
}
render() {
return (
<View style={styles.container}>
<Text>
{this.state.name}
</Text>
<ChangeButton updateMainState={this.changeName}/>
</View>
);
}
}
In the code above, we passed changeName function into the ChangeButton element. The Button in ChangeButton calls the function of the parent element when you press it, which manipulates the state of the main class.
Here is the working code: ProjectLink
How can a component be moved from one part of the render hierarchy to another while maintaining component state? In the example below, the result of the call to setView creates a new view (as seen by a new instanceValue number), even though I pass what looks like the existing view.
class TestTo extends React.Component {
constructor(props) {
super(props);
this.state = {
instanceValue: parseInt(Math.random() * 100)
}
}
render() {
return <Text>{this.state.instanceValue}</Text>
}
}
class TestFrom extends React.Component {
constructor(props) {
super(props);
this.state = {
view: <TestTo />
}
}
doSet = () => {
this.props.nav.setView(this.state.view);
}
render() {
return <View>
<Button title="doaction" onPress={this.doSet} />
{this.state.view}
</View>
}
}
class Holder extends React.Component {
constructor(props) {
super(props);
this.state = {
view: <TestFrom nav={this} />
}
}
setView = (view) => {
this.setState({view: view});
}
render() {
return this.state.view
}
}
<Holder />
i want to pass my params value in my custom component so below is my code
Header.js
class Header extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View >
<Text >Title</Text>
<Text>subtitle</Text>
</View>
);
}
}
I call my Header.js from my main.js
class Main extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Header title = {this.props.navigation.state.params.screen_title} subtitle= {this.props.navigation.state.params.subtitle} />
);
}
}
I pass my title and subtitle in my header component , i just wanted to know how can i access my passing variable value in my header component ? your all suggestions are appreciable
Its very simple You can access it by
this.props.title
this.props.subTitle
this.props.nameOfTheProps
I'd like to, in my router on renderScene, be able to have a property of scenes/components etc. to hide the Navigator bar.
Unfortunately, I can't modify the state of the navigationbar, and have a re-render fire with conditions. I guess that's because of the way it's set?
export default class Root extends React.Component {
render(){
return (
<Navigator
initialRoute={Routes.SubdomainScreen}
renderScene={Router.renderScene}
configureScene={Router.configureScene}
navigationBar={
<Navigator.NavigationBar
routeMapper={NavigationBarRouteMapper}
/>
}
style={styles.container}
/>
)
}
}
Ideally, in my router, some components with have navigationbar set to false, and I will then update the style of the navigator to {opacity:0}. When/where would someone accomplish this?
You can use your route definitions and add a hideNavBar property to it, then track it with state.
export default class Root extends React.Component {
constructor(props) {
super(props);
this.state = {
hideNavBar: false,
};
}
render(){
let navBar = null;
if (! this.state.hideNavBar) {
navBar = (
<Navigator.NavigationBar
routeMapper={NavigationBarRouteMapper}
/>
);
}
return (
<Navigator
initialRoute={Routes.SubdomainScreen}
renderScene={Router.renderScene}
configureScene={Router.configureScene}
onWillFocus={this.onNavWillFocus.bind(this)}
navigationBar={navBar}
style={styles.container}
/>
)
}
onNavWillFocus(route) {
if (route.hideNavBar !== undefined && this.state.hideNavBar !== route.hideNavBar) {
this.setState({hideNavBar: route.hideNavBar});
}
}
}