perform onclick event in reactjs - javascript

I am trying to make an application using reactjs.below is the code which present in my main app.js:
class App extends Component {
return (
<div>
<ExampleTable
header={() => <TopBar/>}
/>
<AddExampleModal/>
<ChartModal/>
<CompatibilityAlert/>
</div>
)
}
}
where Top Bat,AddExampleModal , ChartModal and CompatibilityAlert are loaded from other js files.
Chartmodal contains:
class ChartModal extends Component{
constructor(props){
super(props)
}
render(){
return(
<Modal
onOk={()=>console.log('ok')}
onCancel={()=>console.log('cancel')}
visible={true}
okText={'ok'}
cancelText={'cancel'}
confirmLoading={false}
title="Intent distribution chart"
>
<h1>HOWDY</h1>
<TreeMap
data={chartData}
width={400}
valueUnit={'count'}
/>
</Modal>
)
}
}
Topbar contains :
class TopBar extends Component {
render{
return (
<Button
style={styles.button}
type='primary'
// onClick={() => changechartshow()}
>
Show Graph
</Button>
)
}
}
The thing is that in the app file,i want to toggle the visibility of chartmodal using the button in the topbar.

App
class App extends Component {
constructor() {
this.state = {
isVisible: true
}
}
toggleVisibility = () => this.setState({isVisible: !this.state.isVisible})
render () {
const {isVisible} = this.state;
return (
<div>
<ExampleTable
header={() => <TopBar toggleVisibility =
{this.toggleVisibility.bind(this)}
/>}
<AddExampleModal/>
<ChartModal isVisible={isVisible}/>
<CompatibilityAlert/>
</div>
);
}
}
TopBar
class TopBar extends Component {
render{
return (
<Button
style={styles.button}
type='primary'
onClick={() => this.props.toggleVisibility()}
>
Show Graph
</Button>
)
}
}
ChartModal - Pass the state to visible attribute
class ChartModal extends Component{
constructor(props){
super(props)
}
render(){
return(
<Modal
onOk={()=>console.log('ok')}
onCancel={()=>console.log('cancel')}
visible={this.props.isVisible}
okText={'ok'}
cancelText={'cancel'}
confirmLoading={false}
title="Intent distribution chart"
>
<h1>HOWDY</h1>
<TreeMap
data={chartData}
width={400}
valueUnit={'count'}
/>
</Modal>
)
}
}

You can add a state in your App component and pass an handler to update the state from the TopBar component. Based on this state you can toggle the visibility of ChartModal.
class App extends Component {
state = {
isVisible: true
}
toggleVisibility = () => {
this.setState(prevState => ({isVisible: !prevState.isVisible}))
}
return (
<div>
<ExampleTable
header={() => <TopBar toggleVisibility={this.toggleVisibility}/>}
/>
<AddExampleModal/>
{this.state.isVisible ? <ChartModal/>: null }
<CompatibilityAlert/>
</div>
)
}
}
Now in your TopBar you will call this function as
class TopBar extends Component {
render{
return (
<Button
style={styles.button}
type='primary'
onClick={() => this.props.toggleVisibility()}
>
Show Graph
</Button>
)
}
}
Read the React docs here on Lifting the state up for a detailed explanation

Related

I can't update state in child component

i wanna change state value in child component but i getting always 'this.setState is not a function ' error
Parent Component
`
export default class Todo extends Component {
constructor(props){
super(props)
this.state = {
propBottomMenu : false
}
this.bottomRef = React.createRef()
};
checkClose(){
this.setState({propBottomMenu : false})
}
render() {
return (
<>
// other codes
<TouchableOpacity
onPress={() => this.setState({propBottomMenu : false})}
style={styles.addTask}
>
<FontAwesomeIcon icon={ faPlus } size={25} color={'#fff'} />
</TouchableOpacity>
{this.state.propBottomMenu ?
<BottomMenu bSheetRef={this.bottomRef} checkClose={this.checkClose} style= {styles.bottomMenu} />
: null}
</>
)
}
}
`
Child Component :
`
export default class BottomMenu extends Component {
constructor(props){
super(props)
this.bottomRef = this.props.bSheetRef
}
render() {
return (
<>
<BottomSheet
ref={this.bottomRef}
snapPoints={[ '40%', '60%', '90%']}
index={1}
enablePanDownToClose={true}
onChange={(index)=>{ index < 0 && this.props.checkClose() }}
>
// other codes
</BottomSheet>
</>
)
}
}
})
`
checkClose() function working but i can't update state
Error : this.setState is not a function
Solution :
For the function to work we must use bind or call it as arrow function
constructor(props){
super(props)
this.checkClose = this.checkClose.bind(this); // this line
this.state = {
propBottomMenu : false
}
this.bottomRef = React.createRef()
};
Jsx:
<BottomMenu bSheetRef={this.bottomRef} checkClose={this.checkClose} style={styles.bottomMenu} />

How to detect screen change in class component with navigation v6?

I just want to clear the state when you move to any other screen in my class component when I'm using navigation v6 (I saw some coments about function component but not class), so I will explain briefly
I did a clean state function in my Body component
class InputBody extends Component {
constructor(props) {
super(props);
this.state = {
fields: JSON.parse(this.props.route).message,
};
}
reset () {
this.setState({});
}
render() {
return (
<Fragment>
{Object.keys(JSON.parse(this.props.route).message).length > 0 ? (
<FieldArraysForm all={JSON.parse(this.props.route).message} resetForm={reset} native={this.props} />
) : (
<ActivityIndicator size="large" color="#eb6b09" />
)}
</Fragment>
);
}
}
And then I call it in my fields array component
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
class FieldArraysForm extends Component {
render() {
const {handleSubmit} = this.props.native;
// event listener
const getFields = async (values) => {
return sleep(500).then(() => {
console.log(JSON.stringify(values))
this.props.resetForm();
})
}
return (
<Form>
{this.props.all.map((item) => (
<Field
key={item._id}
name={`customInput.${item._id}`}
component={RenderField}
label={item.field}
type={item.typeFieldAltText}
/>
))}
<View>
<TouchableOpacity onPress={handleSubmit(getFields)}>
<Text>Save Form</Text>
</TouchableOpacity>
</View>
</Form>
);
}
}
Render field function component
class RenderField extends Component {
render() {
return (
<Fragment>
<Texto>{this.props.label}</Texto>
<TextInput
onChangeText={this.props.input.onChange}
{...this.props.input}
keyboardType={this.props.type}
/>
</Fragment>
);
}
}
So how can I call this.prop.reset() on screen change using class component with react navigation v6 ?

How to display different components when clicking a button on one page?

I am trying to display different Components when I click a button with my OnClick in the Render Function of my App.js.
I would like to show a certain component when the button is clicked and it hides the other components.
this is an example of what I want to do
return (
<div className={styles.container}>
<img className={styles.image} src={image} alt="COVID-19" />
//If the Country Button which is the default is clicked show This
<ThemeProvider theme = {theme}>
<CountryPicker handleCountryChange={this.handleCountryChange} />
<CountryCards CountryData = {CountryData} CountryYesterdayData = {CountryYesterdayData}/>
</ThemeProvider>
<Chart countrydailydata ={countrydailydata} />
//If the State Button is clicked show this
<ThemeProvider theme= {theme}>
<StatePicker handleStateChange={this.handleStateChange} />
<StateCards stateData= {stateData} yesterdayStateData = {yesterdayStateData}/>
</ThemeProvider>
//If the City Button is clicked show this
<CityPicker handleCityChange={this.handleCityChange}/>
<CityCard cityData = {cityData}/>
</div>
);
import React from 'react';
import logo from './logo.svg';
import './App.css';
function Statepicker(){
return(
<div>Statepicker</div>
)
}
function Statecards(){
return(
<div>Statecards</div>
)
}
function Countrypicker(){
return(
<div>Countrypicker</div>
)
}
function Countrycards(){
return(
<div>Countrycards</div>
)
}
class ThemeProvider extends React.Component{
constructor(props){
super(props);
this.state={country:true,states:false}
}
renderCountryOrState=()=>{
if(this.state.states){
return(<React.Fragment>
<Statepicker/>
<Statecards/>
</React.Fragment>)
}
return (
<React.Fragment>
<Countrypicker/>
<Countrycards/>
</React.Fragment>
)
}
render(){
return(
<div>
<button onClick={(e)=>{this.setState({country:true,states:false})}}>Select country</button>
<button onClick={(e)=>{this.setState({country:false,states:true})}}>Select state</button>
{this.renderCountryOrState()}
</div>
)
}
}
function App() {
return (
<ThemeProvider/>
);
}
export default App;
import React from "react";
import { Button, View } from "react-native";
import styles from "./App.module.css";
import {View} from 'react-native'
import image from "./images/covid1.png";
class App extends React.Component {
constructor(props){
super(props);
state = {
CityButton: false,
StateButton: false,
CountryButton: false
};
}
render() {
{ CountryButton, StateButton, CityButton } = this.state;
return (
<view>
<div className={styles.container}>
<img className={styles.image} src={image} alt="COVID-19" />
<Button title="Country Mode" onPress={() =>
this.setState({CountryButton: true}
)} />
<Button title="State Mode" onPress={() =>
this.setState({StateButton: true}
)} />
<Button title="County Mode" onPress={() =>
this.setState({CityButton: true}
)} />
{CountryButton && <div> Hello </div>}
{StateButton && <div> Hello </div>}
{CityButton && <div> Hello </div>}
</div>
</view>
);
}
}
export default App;

getting the value of child component

I'm trying to get the value of child component yet not successful. Here what I am working on ...
import React from "react";
import Tooltip from "rc-tooltip";
import Slider, { Range } from "rc-slider";
const Handle = Slider.Handle;
const handle = props => {
const { value, dragging, index, ...restProps } = props;
return (
<Tooltip
prefixCls="rc-slider-tooltip"
overlay={value}
visible={dragging}
placement="top"
key={index}
>
<Handle value={value} {...restProps} />
</Tooltip>
);
};
const Slider = props => {
return (
<div>
<div style={{ width: 300, margin: 30 }}>
<p>{this.props.title}</p>
<Slider min={0} max={10} defaultValue={5} handle={handle}/>
</div>
</div>
);
};
export default Slider;
Main App.js
import Slider from '.....'
class App extends Component{
constructor(props){
super(props);
this.state = {
val: 0
}
}
render() {
return(
<Slider onChange={this.state.value} />
)
}
}
I am looking to get the value to be updated to this App.js state as the slider is being dragged. onChange is not updating the state. How should I modify so that slider value gets updated on this.state.value.
The Slider component from rc-slider has an onChange prop event which is a function. You need to pass this method to slider and update the state instead of just passing the state value
import React from "react";
import Tooltip from "rc-tooltip";
import Slider, { Range } from "rc-slider";
const Handle = Slider.Handle;
const handle = props => {
const { value, dragging, index, ...restProps } = props;
return (
<Tooltip
prefixCls="rc-slider-tooltip"
overlay={value}
visible={dragging}
placement="top"
key={index}
>
<Handle value={value} {...restProps} />
</Tooltip>
);
};
const Slider = props => {
return (
<div>
<div style={{ width: 300, margin: 30 }}>
<p>{this.props.title}</p>
<Slider min={0} max={10} defaultValue={5} onChange={props.onChange} handle={handle}/>
</div>
</div>
);
};
export default Slider;
class App extends Component{
constructor(props){
super(props);
this.state = {
val: 0
}
}
onChange=(value) => {
this.setState({val: value});
}
render() {
return(
<Slider onChange={this.onChange} />
)
}
}
Here is the Live code
https://codesandbox.io/s/n9y97y55kp
Let me know if you have any doubts
You just have to pass the event from child to parent component to update the values.
according to rc-slider document, you should pass a function to Slider onChange.
import Slider from '.....'
class App extends Component {
constructor(props) {
super(props);
this.state = {
val: 0
}
}
handleSliderChange = (value) => {
console.log(value) // maybe a string or a object
this.setState({val: value})
}
render() {
return (
<Slider onChange={this.handleSliderChange} />
)
}
}
above code should work

React Native - Execute child function from Parent Button onPress

Disclaimer : I'm new to RN. I have already tested multiple solutions from other similar questions without success so far.
I have a Parent that render two Childrens like this
export default class ParentComponent extends Component {
constructor(props) {
super(props)
}
render() {
return (
<View>
<Foo name="a" ref={foo => {this.foo = foo}} {...this.props} />
<Text>-----------</Text>
<Foo name="b" />
<Text>-----------</Text>
<Button
onPress={this.foo.myFunction()}
title="Start"
color="#841584"
/>
</View>
)
}
}
My class Foo has a function inside it that start some process :
class Foo extends Component {
myFunction(){
// Some stuff here
}
}
How can I call this myFunction for my Child when I press on the Button ? Optionally, is it possible with only one onPress, to call the function for both Child and avoid creating two Button for each Child ?
You can use refs
https://reactjs.org/docs/refs-and-the-dom.html
Example:
class Parent extends Component {
render() {
return (
<View>
<Child ref={instance => { this.child = instance; }} />
<TouchableOpacity onPress={() => { this.child.clicked(); }}>
<Text>Click</Text>
</TouchableOpacity>
</View>
);
}
}
class Child extends Component {
clicked() {
alert('clicked');
}
render() {
return (
<Text>Hello</Text>
);
}
}
Hope it helps
Basically what I did is to call a local function when onPress and change the state of the Parent. I pass this state to the Child during its creation. And since the Child are updated (if needed) when the Parent's state change this do the trick.
export default class ParentComponent extends Component {
constructor(props) {
super(props)
this.state = {
activity: false
}
}
onButtonPress = () => {
this.setState({
activity: !this.state.activity
});
}
render() {
return (
<View>
<Foo name="a" activity={this.state.activity} />
<Text>-----------</Text>
<Foo name="b" activity={this.state.activity} />
<Text>-----------</Text>
<Button
onPress={this.onButtonPress}
title="Start"
color="#841584"
/>
</View>
)
}
}
class Foo extends Component {
myFunction(){
// Some stuff here
}
componentWillReceiveProps(newProps) {
if (newProps.activity === true) {
this.myFunction();
}
}
}
It's better to do myFunction logic inside ParentComponent and setState the data which can be passed into child ie:Foo.
constructor(props) {
super(props);
this.state = {
fooData: initialValue,
}
}
myFunction = () => {
// Some stuff here
this.setState({ fooData: someValue })
}
render() {
return (
<View>
<Foo name="a" data={this.state.fooData} {...this.props} />
<Text>-----------</Text>
<Foo name="b" data={this.state.fooData}/>
<Text>-----------</Text>
<Button
onPress={this.myFunction}
title="Start"
color="#841584"
/>
</View>
)
}
and you can make the changes inside Foo accordingly
class Foo extends Component {
render() {
const { data } = this.props;
return(
//Use data here to make change
)
}
}

Categories

Resources