Not rendering component onClick - javascript

The component I am trying to render:
import React, { Component } from 'react';
export default class QueryPrint extends Component {
render() {
console.log('working');
return (
<div>Hello</div>
)
}
}
The component that is trying to call it:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import {
Button,
} from 'reactstrap';
import QueryPrint from './bq_print';
class QueryResults extends Component {
constructor(props) {
super(props);
this.print = this.print.bind(this);
}
print() {
console.log('Clicked');
return (
<QueryPrint />
);
}
render() {
return (
<Button
className='cuts-btn'
color='success'
onClick={this.print}
>
Print
</Button>
)
}
}
function mapStateToProps(state) {
return {
query_data: state.results.query_data
}
}
export default connect (mapStateToProps, null)(QueryResults);
The console.log('clicked') is working, but the component that is supposed to render in that method doesn't--no console.log('working') or <div>.

Returning something from a click callback has no effect. If you want to render something, you do so in the render method. The click callback's job is to call this.setState(), which will then kick off a render.
Perhaps something like this:
class QueryResults extends Component {
constructor(props) {
super(props);
this.print = this.print.bind(this);
this.state = {
queryPrint: false,
}
}
print() {
console.log('Clicked');
this.setState({ queryPrint: true })
}
render() {
const { queryPrint } = this.state;
return (
<React.Fragment>
{queryPrint && <QueryPrint />}
<Button
className='cuts-btn'
color='success'
onClick={this.print}
>
Print
</Button>
</React.Fragment>
)
}
}

React Native works differently. It is more like a web app - you need to navigate to the other component.
Look at this example its very to the point: https://facebook.github.io/react-native/docs/navigation
Alternatively if you want to make only part of the screen change you will need to include it into your own render and control it thru a flag or a state machine.
https://facebook.github.io/react-native/docs/direct-manipulation

Related

Using button in one component to render another component in main (App) component

I am trying to display/hide one component which is ItemMain and which is imported to the main App component using button in another component which is NavLogoNew. I tried to do this in many different ways but it looks like the button doesn't know if it's clicked, when I change true/false manually it works. In web I found a lot of stuff about situations when only two components are involved, but nothing like this. My code:
App
import React from 'react';
import './App.css';
import { tsPropertySignature } from '#babel/types';
import { statement } from '#babel/template';
import NavBar from './../Components/Navigation/NavBar/NavBar.js';
import ItemMain from './../Components/Item/ItemMain/ItemMain.js';
import ItemList from './../Components/Item/ItemList/ItemList.js';
import NavButtonTop from './../Components/Navigation/NavButton/NavButtonTop/NavButtonTop.js';
import NavLogoNew from './../Components/Navigation/NavButton/NavButtonNew/NavLogoNew.js';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
visible: !this.visible
})
}
render() {
return (
<div className="App">
<NavBar />
{this.state.visible ? <ItemMain /> : null}
<ItemList />
<NavButtonTop name='UP'/>
</div>
);
}
}
export default App;
NavLogoNew:
import React from 'react';
import './NavLogoNew.css';
import ItemMain from './../../../Item/ItemMain/ItemMain.js'
class NavLogoNew extends React.Component {
render() {
return (
<button
className='NavLogoNew'
onClick={this.props.click}
>
{this.props.name}
</button>
);
}
}
export default NavLogoNew;
Your handleClick function is lacking something
use !this.state.visible so change from the below
handleClick(){
this.setState({
visible: !this.visible
})
}
to
handleClick = () => {
this.setState({
visible: !this.state.visible
})
}
pass the handleClick function to the NavLogoNew as follows
<NavLogoNew onClick = {this.handleClick} />
inside of the NavLogoNew component you should invoke it as follows
class NavLogoNew extends React.Component {
render() {
return (
<button
className='NavLogoNew'
onClick={() => this.props.onClick()}
>
{this.props.name}
</button>
);
}
}

How to change className?

So I keep div element in my state. I want to change it's className in response to onClick event. I know I could do it with event.target.className but the code below is only the sample of a biggest application and it's not possible to use it there. As a resultant from changeClass function I get
"TypeError: Cannot assign to read only property 'className' of object '#'".
So I wonder is there any other way to do it?
import React, { Component } from "react";
import "./styles/style.css";
class App extends Component {
constructor(props) {
super(props);
this.state = {
myDiv: [
<div
id="firstDiv"
key={1}
className={"first"}
onClick={this.changeClass}
/>
]
};
}
changeClass = () => {
this.setState(prevState => {
return { myDiv: (prevState.myDiv[0].props.className = "second") };
});
};
render() {
return <div>{this.state.myDiv.map(div => div)}</div>;
}
}
export default App;
Don't put your jsx in state. only add className and state and onChangeClass use this.stateState to update className.
import React, { Component } from "react";
import "./styles/style.css";
class App extends Component {
constructor(props) {
super(props);
this.state = {
className:"first"
};
}
changeClass = () => {
this.setState({ classNmae: "two" });
};
render() {
return <div>
<div
id="firstDiv"
className={this.state.className}
onClick={this.changeClass}
/>
</div>;
}
}
export default App;
there's a simpler option try this:
import React, { Component } from "react";
import "./styles/style.css";
class App extends Component {
constructor(props) {
super(props);
this.state = {
className: "first"
};
}
changeClass = () => {
this.setState({className: "second"});
};
render() {
return <div
id="firstDiv"
className={this.state.className}
onClick={this.changeClass}>
</div>;
}
}
export default App;
You can use Hooks if you use a React version upper than 16.8
import React, { useState } from "react"
import "./styles/style.css"
const App = () => {
const [myClass, setMyClass] = useState("first")
const changeClass = () => {
setMyClass("second")
}
render() {
return <div
id="firstDiv"
className={myClass}
onClick={changeClass}>
</div>;
}
}
export default App

Trigger setState function in parent from promise.then in child

I am trying to find a solution to setState from a parent within child promise.
The parent component is
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
transition: false
};
}
handleTransition = () => {
this.setState(state => ({ transition: !state.transition }));
};
render() {
return <Child handleTransition={this.handleTransition} />;
}
}
of which this.props.handleTransition is to be triggered from a child component as
class Child extends Component {
constructor(props) {
super(props);
this.state = {};
}
onSubmit = event => {
firebase
.doCreateUserWithEmailAndPassword(email, password)
.then(() => {
// Trigger this.props.handleTransition here
})
...
Where this.props.handleTransition is wanting to be triggered with then of onSubmit
Please let me know if you require more detail? I would prefer not to use a library or package to achieve this but if it makes life easier I may consider. Redux is likely the best option but I would prefer not to unless necessary.
Note: this.props.handleTransition(); does the job but esLint returns an error of Must use destructuring props assignmenteslint(react/destructuring-assignment) and I am considering that this method is not the correct method.
// --- parent.js
import React, { Component, Fragment } from "react";
import { ChildComponent } from './containers/child'
class ParentContainer extends Component {
handleUpdate = () => {
// whatever you want to do here
}
render(){
return (
<Fragment>
<ChildComponent onUpdate={this.handleUpdate} />
</Fragment>
);
}
}
export default ParentContainer;
// --- child.js
import React, { Component, Fragment } from "react";
export class ChildComponent extends Component {
this.someAsyncFunction = () => {
fetch('/just/for/example')
.then(res =>
// Do whatever you need here, then hit your function on parent by bubbling the request up the chain
this.props.onUpdate();
)
}
render(){
return (
// whatever you want to do with this data
);
}
}

React Native pass function to child component as prop

I'm new to React Native (and React), and I'm trying to pass a function as a prop to a component.
My goal is to create a component where its onPress functionality can be set by the instantiator of the component, so that it is more reusable.
Here is my code so far.
App.js
import React, { Component } from 'react';
import { View } from 'react-native';
import TouchableButton from './components/touchable-button';
export default class App extends Component<Props> {
constructor () {
super();
}
handlePress () {
// this should be called when my custom component is clicked
}
render () {
return (
<View>
<TouchableButton handlePress={this.handlePress.bind(this)}/>
</View>
);
}
}
TouchableButton.js
import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';
import AppButton from "./app-button";
export default class TouchableButton extends Component {
handlePress;
constructor(props){
super(props);
}
render () {
return (
<TouchableHighlight onPress={
this.props.handlePress
}>
<AppButton/>
</TouchableHighlight>
);
}
}
I am passing the handlePress function as the prop handlePress. I would expect the TouchableButton's props to contain that function, however it isn't there.
Solution
Use arrow function for no care about binding this.
And I recommend to check null before calling the props method.
App.js
export default class App extends Component<Props> {
constructor () {
super();
}
handlePress = () => {
// Do what you want.
}
render () {
return (
<View>
<TouchableButton onPress={this.handlePress}/>
</View>
);
}
}
TouchableButton.js
import React, { Component } from 'react';
import { TouchableHighlight } from 'react-native';
import AppButton from "./app-button";
export default class TouchableButton extends Component {
constructor(props){
super(props);
}
handlePress = () => {
// Need to check to prevent null exception.
this.props.onPress?.(); // Same as this.props.onPress && this.props.onPress();
}
render () {
return (
<TouchableHighlight onPress={this.handlePress}>
<AppButton/>
</TouchableHighlight>
);
}
}
When writing handlePress={this.handlePress.bind(this)} you passing a statement execution ( which when and if executed returns a function). What is expected is to pass the function itself either with handlePress={this.handlePress} (and do the binding in the constructor) or handlePress={() => this.handlePress()} which passes an anonymous function which when executed will execute handlePress in this class context.
// Parent
handleClick( name ){
alert(name);
}
<Child func={this.handleClick.bind(this)} />
// Children
let { func } = this.props;
func( 'VARIABLE' );

event not firing on react component using arrow function

import React, { Component } from 'react'
import { connect } from 'react-redux'
#connect(
state=>state.user
)
class Profile extends Component {
logout(){
alert('logout')
}
render() {
const props = this.props
return props.user && (
<div>
<button onClick={()=>{this.logout()}}>Logout</button>
</div>
)
}
}
export default Profile
I click on the button, the alert is not triggered, no error no warning now I'm lost. What can be the possible cause?
I tried below code and everything seems fine. May be your this.props is not having any value. Can you share that code as well. I see everything is fine in component.
class Hello extends React.Component {
logout(){
alert('logout')
}
render() {
return (
<div>
<button onClick={()=>{this.logout()}}>Logout</button>
</div>
)
}
}
ReactDOM.render(
,
document

Categories

Resources