How to Change Title Attribute in React Native Button Component - reactjs

I have a few React components that look something like this within an app:
<View style={{margin: 5}}>
<Button title='Enable Headlights' color='#00759A' onClick={doChanges}/>
</View>
I want the Button component to change its color and text whenever its clicked. I was planning on having the function doChanges do this, but I can't figure out a way to modify the title and color attributes. I've seen custom made components that make these kinds of changes in state by calling setState within the component, but Button isn't a component that I made. I tried doing something along the lines of:
var text = "Enable headlights"
function doChanges(text) {
text = "Disable headlights"
}
<View style={{margin: 5}}>
<Button title={text} color='#00759A' onClick={()=> {doChanges(text)}}/>
</View>
But that doesn't seem to work the way I want it to. I think it's because even though the variable text is changing, the actual component isn't rerendering, so the changes in text never actually appear.
There doesn't seem to be a way to force the component to rerender, and I don't see how there's a way I can modify the title and color attributes of the Button component.
Do I have to make a custom component that's subclassed from Button in order to get the functionality I want? Or is there a specific way for how I'm supposed to go about doing something like this in React?
Any help would be appreciated!

If you are supposed to make changes at the UI level then you should use the state to render the updated view.
like:
If you are using Class Component:
class Demo extends Component {
constructor(props) {
super(props)
this.state = {
buttonText: "Enable headlights"
}
this.doChanges = this.doChanges.bind(this);
}
function doChanges(text) {
this.setState({ buttonText: "Disable headlights" });
}
render() {
return (
<View style={{margin: 5}}>
<Button title={this.state.} color='#00759A' onClick={()=> {doChanges(text)}}/>
</View>
)
}
}
If you are using Functional Component:
const Demo = props => {
const [buttonText, setButtonText] = useState("Enable headlights")
function doChanges(text) {
setButtonText("Disable headlights");
}
return (
<View style={{margin: 5}}>
<Button title={text} color='#00759A' onClick={()=> {doChanges(text)}}/>
</View>
)
}
check out more about the state:
https://reactjs.org/docs/state-and-lifecycle.html

Related

React change class attributes

I'm trying to change class attribute in a function, I have a button and I want to change the text as soon as the user clicks it.
I wrote a class and everything but when the user clicks the button nothing happens!
I console logged to see if the variables actually changed and they did so why does it happen?
Here is my code:
class App extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
buttonStatus: 'Post room',
value: '',
}
}
PostANewRoomScreen = () => {
let {data} = '';
return (
<View style={{padding: 15}}>
<TouchableOpacity
style={styles.button}
disabled={this.state.loading}
onPress={() => this.postroom(data)}
>
<Text style={{color: "white" , fontSize: hp('2.5%'), padding: 5}}>
{this.state.loading && <Animated.Image style={{height: hp('3%'), width: wp('2%')}} source={{uri: 'https://media0.giphy.com/media/JTVkOqJ1RyYEBnyoRb/giphy.gif'}} />}
{this.state.buttonStatus}
</Text>
</TouchableOpacity>
</View>
postroom = (value) => {
this.state.loading = true;
this.state.buttonStatus = "button clicked!";
}
this.state.loading = true;
this.state.buttonStatus = "button clicked!";
This does not re render component. You have to use useState Hook (in funcation component) or setState() (in class component) in order to update the state. I suggest converting component to functional component and use hooks to manage state.
const [buttonStatus, setButtonStatus] = useState('Post Room');
then use setButtonStatus(value) inside your postroom function.
Please refer react doc for useSate Hooks
Further, Your existing code has some issues. you are trying to access and mutate state of App component. if you need to share the component state try to lift the state up. If you need to pass properties to component use props.

React Native: Invariant Violation: Text strings must be rendered within a <Text> component

Alright, so I'm a bit new to react, and I've made a sample login screen like so:
export default class App extends Component{
constructor(props){
super(props);
this.state = {
login: '',
password: '',
// exists: false,
Button: './submitButton.png',
}
}
render() {
return (
<View>
//Login form here
<View style={styles.container}>
<TextInput
styles = {styles.container}
placeholder = "Login"
onChangeText = {(login) => this.setState({login})}
/>
<TextInput
styles = {styles.container}
placeholder = "Password"
onChangeText = {(password) => this.setState({password})}
/>
</View>
//Button here
<View style={styles.container}>
<TouchableHighlight
onPress = {() => Alert.alert("Alert!")}
>
<Image
style={styles.button}
source={require('./submitButton.png')}
/>
</TouchableHighlight>
</View>
</View>
);
}
}
But I get the error below:
Originally I had used a Button instead of TouchableHighlight because as I understand it, react-native 0.56 (the version I'm using) has a bug regarding buttons, and apparently gives the same issue as above, and the workaround was supposedly to use a TouchableHighlight or TouchableOpacity. But switching to a TouchableOpacity didn't really seem to fix anything.
What do? I've scoured google but I can't seem to find a solution.
(If there's no hope, is there a way to downgrade my installation of react without breaking nearly everything?)
In JSX, comment like //Login form here doesn't work. It will be treated as a text.
You have to change your comments into the shape like below
{/* Login form here */}

React native should I pass props or use Redux

So I have a router component which sits at the top of the screen in my app. There is a menu button in this component which is visible when certain other pages/components are loaded.
When this menu button is clicked, I need to communicate this to the component which is currently displaying the page so that it can display a context menu.
The context menu and the menu button both work independently. However, I'm confused at how to wire it up. How do I efficiently communicate a true/false toggle between those two components? I thought I could do it with props but then I feel that you cannot update the props after they've been passed. This leads me to think I may need to have a store implemented which both components can read/write from/to. This way the router component will update the store on each menu button click, and the other component could have its state updated based on the store's state which I could use to toggle the menu visible/hidden.
Does that make sense and if so what's the best way of tackling it?
Router code: - Parent, menu() fires when clicking the Menu button
const RouterRecipeComponent = () => {
function menu() {
console.log('clicky');
}
const MenuIcon =
(<TouchableOpacity
onPress={() => menu()}
style={{ backgroundColor: 'red', width: 30, height: 30 }}
>
<Text>MENU</Text>
</TouchableOpacity>);
return (
<Router
sceneStyle={styles.sceneStyleWithSettings}
navigationBarStyle={styles.navBar}
titleStyle={styles.navBarTitle}
barButtonIconStyle={styles.barButtonIconStyle}
>
<Scene
key="Recipes"
component={Recipes}
title={content.recipe_heading}
rightTitle="Menu" initial
renderRightButton={() => MenuIcon}
/>
Recipes code - Displays a bunch of stuff including the settings panel (code included) which will be toggled visible/hidden on each click of the menu button in the above Router code. So my thoughts are to be able to toggle the state settingsPanel true/false to display the below:
renderSettingsPanel() {
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
if (this.state.settingsPanel === true) {
return (
<View style={styles.settingsPanel}>
{this.theSettings()}
</View>
);
}
return (
<View style={[styles.settingsPanel, { top: -80, position: 'absolute', opacity: 10 }]}>
{this.theSettings()}
</View>
);
}

How can I create a modal and render it on the fly?

I am building my first app in React Native, I have a ListView that displays a number of items and each one is clickable. My question is when I click on a row I would like a modal to appear above. Similar in IOS to clicking and the adding a subview.
renderRow( rowData ){
return (
<TouchableHighlight onPress={() => this.pressRow()}>
<View style={styles.parcelInfoContainer}>
</View>
</TouchableHighlight>
);
}
Now the problem is I am unsure about what to do in the function called by pressRow in relation to rendering the new component. In IOS I would simply add the view at this point but I am not sure how to go about it in React Native. I understand the idea of components just not how to render a new component on the fly.
If you're going to render the same Modal, in terms of layout, you should define it in render() function. Rendering on the fly is not possible, but you can change the states to make modal show what you like.
onPressRow = (dataFromRow) => {
this.setState({
modalText: dataFromRow.text
})
this.showModal(); //Call your function to show modal
}
render() {
return (
<View>
<FlatList />
<Modal>
<View>
...
<Text>{this.state.modalText}</Text>
</View>
</Modal>
</View>
)
}
However, if you want different layout for each row, you should write a this.getModalContent() like function to determine which layout should be rendered. You should call this function in render => <Modal> {this.getModalContent()} </Modal>
getModalContent = () => {
switch (this.state.modalText) { // define a better logic here.
case 'a':
return ( <Text> hey </Text>)
...
}
}

How to add a button in react native environment?

could you please tell me how to add button in view using react native .
here is my code
https://rnplay.org/apps/0TPePA
can I used this this
https://npmcdn.com/react-native-button#1.6.0
in my demo ?
I need to add button in my view here is code
class First extends Component {
render (){
return (<View><Text>"hello"</Text>
</View>
)
}
}
Creating a button yourself is quite simple. You can use toucableopacity and the onPress method attached to it.
Put the following in your render method
<TouchableOpacity onPress={this._onButtonPress}>
<Text>Button Text</Text>
</TouchableOpacity>
And put this in a react function.
_onButtonPress: function () {
console.log ("Button has been pressed");
}
To make it look more like a button you can add styling directly to the <Text style={{flex: 1, backgroundColor: 'blue', etc...}}

Resources