How do I communicate with my stateless component in React? - reactjs

I wanted to create a very simple app containing a button. When I click on it it should change it's name and should change it's state to: isDisabled:true. I accomplished this by writing button inline, giving it an OnClick and so on, but I wanted to try this with stateless component with the same functionality, however I'm totally stuck.
import React, { Component } from 'react';
import './App.css';
class App extends Component{
constructor(){
super()
this.state = {name:'Hey buddy click me',
isDisabled:false,
}
}
render() {
return (
<div>
<MyButton handleClick={this.handleClick.bind(this)}></MyButton>
</div>
)
}
handleClick = () => {
this.setState ({
name:'Dont click!',
isDisabled:true,
});
}
}
const MyButton = (name, isDisabled) => <button onClick={this.handleClick.bind(this)}>{name}</button>
export default App;

You need to pass name, isDisabled too with handleClick as props if you want to access then in MyButton component.
Though name can also be passed as children. But as i feel you are learning start passing it as props.Then in future you can use children.
import React, { Component } from 'react';
import './App.css';
class App extends Component{
constructor(){
super()
this.state = {name:'Hey buddy click me',
isDisabled:false,
}
}
render() {
return (
<div>
<MyButton
name={this.state.name}
isDisabled={this.state.isDisabled}
handleClick={this.handleClick.bind(this)}>
</MyButton>
</div>
)
}
handleClick = () => {
this.setState ({
name:'Dont click!',
isDisabled:true,
});
}
}
//here we need to receive props from parent components, if we need to use here
const MyButton = ({name, isDisabled, handleClick}) => <button onClick={handleClick}>{name}</button>
export default App;

Related

How to call functional child component method from class parent component

I have a class based parent component like below
import React from "react";
import ReactDOM from "react-dom";
import FunChild from "./FunChild";
class App extends React.Component {
constructor(props) {
super(props);
this.childRef = React.createRef();
this.parentmethodFun = this.parentmethodFun.bind(this);
}
parentmethodFun() {
this.childRef.current.childmethod();
}
render() {
return (
<div>
<FunChild />
<button type="button" onClick={this.parentmethodFun}>
function
</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("container"));
the funChild.js file
import React from "react";
function FunChild(props) {
childmethod() {
console.log("child method is called");
}
return (<div>This is child ...!</div>);
}
export default FunChild;
if that child was a class component I can very easily use ref={this.childRef} to access child method.
But, it's a functional component and It was giving lot of problems. Can anyone please help me on this.
reference project link https://codesandbox.io/s/react-playground-forked-74xzn?file=/index.js
You should avoid this kind of relation because it is not the way how react works. In React you should pass everything from up to bottom. But if you reale want to achieve something like this you can use reference forwarding and imperative handler hook. E.g:
import { Component, forwardRef, createRef, useImperativeHandle } from "react";
const Child = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
childMethod() {
console.log("child method is called");
}
}));
return <div>This is child ...!</div>;
});
class App extends Component {
constructor(props) {
super(props);
this.childRef = createRef();
this.parentmethodFun = this.parentmethodFun.bind(this);
}
parentmethodFun() {
this.childRef.childMethod();
}
render() {
return (
<div>
<Child ref={(ref) => (this.childRef = ref)} />
<button type="button" onClick={this.parentmethodFun}>
function
</button>
</div>
);
}
}
Personally, i think you should rethink your application structure as it is very likely that there is a better solution than this trick.

React JSX with component in variable does not sync props

The Scegli component is assigned to the App comp variable and then rendered in App render as a variable. However, the props assigned don't work: if I type in the input box, the value is frozen.
What am I doing wrong?
If I just move the <Scegli>...</Scegli> directly into the render (without assigning to a variable) it works as expected.
App.js
import React, { Component } from 'react';
import './App.css';
import Scegli from './components/Scegli';
class App extends Component {
constructor() {
super();
this.state = {
valore: 'Single'
}
this.comp = <Scegli value={this.state.valore} handleChange={this.setValoreHandler} />;
}
setValoreHandler = e => {
this.setState({
valore: e.target.value
});
}
render() {
return (
<div>
{this.comp}
</div>
);
}
}
export default App;
Scegli.js
import React, { Component } from 'react';
class Scegli extends Component {
render() {
return (
<div>
<input value={this.props.value} onChange={this.props.handleChange} />
Valore scelto: {this.props.value}
</div>
);
}
}
export default Scegli;
this.comp is declared once, at the component's mount and stays in that state. You are not updating/re-rendering it anywhere, that's why it remains unchanged.
You could either:
move the JSX component directly to render:
<div>
<Scegli value={this.state.valore} handleChange={this.setValoreHandler} />
</div>
or
update the class variable with every input change (not recommended though):
setValoreHandler = (e) => {
this.comp = <Scegli value={e.target.value} handleChange={this.setValoreHandler} />;
this.forceUpdate();
}
(I could be wrong) but when you define this.comp in the constructor() it is only loaded once with the default state. The constructor() is not called on re-render (similar to componentWillMount()). So that is why it is frozen as the updated state is never sent this.comp
Instead of this.comp in render do
return (
<div>
<Scegli value={this.state.valore} handleChange={this.setValoreHandler}/>
</div>
);

Props missing after passing to children when using draft-js

I'm kinda new to react and thought that in the constructor function, using super(props) can fully receive the props that passed by parents. But however, I can't get the string test from my parent component.
So in the parent component, I pass the string "test" as props
import React from 'react';
import Post from '../components/post';
import "../components/css/post.css"
class Bulletin extends React.Component {
render()
{
console.log(this.props);
return (
<div>
<Post test={"sent from parent"}/>
</div>
);
}
}
export default Bulletin;
And then in Post.js, I print the props in two places:
import React, { Component } from 'react';
export default class Edit extends Component {
constructor(props) {
super(props);
console.log(props);
}
render() {
console.log(this.props);
return (
<div className="editor" onClick={this.focus}>
</div>
);
}
}
The two outputs are both {className: "editor"} which is not what I need. I need the string {test: "sent from parent"} and don't know why this doesn't works for me.

How to send data from one component to another component in react without parent child relation

Home Component
import React, { Component } from 'react';
import Two from 'components/Two.jsx'
import One from 'components/One.jsx'
class Home extends Component {
constructor(props){
super(props)
this.state = {
}
this.one = React.createRef();
}
getData = (data) => {
this.one.current.finalClick(data);
}
render() {
return (
<div>
<Two shareData={this.getData} />
<One ref={this.one} />
</div>
);
}
}
export default Home;
One Compoent:
import React from 'react'
class One extends React.Component {
constructor(props){
super(props);
this.state={
}
}
finalClick = (data) => {
console.log(data)
}
render(){
return (
<div>
</div>
)
}
}
export default One;
Two Component:
import React from 'react'
class Two extends React.Component {
handleClick = (data) => {
this.props.shareData(data)
}
render(){
return (
<div>
<br/>
<button className="btn btn-info" onClick={() => this.handleClick('hellow')}>click</button>
</div>
)
}
}
export default Two;
Here i am tring to get click one function from from another components.
which is not it's parent or child componet.
First I am clicking the button in two and it is sending data to Home Component.
And it is logging the data.
And i wants to send data to finalClick() method in the same time after getData() called in Home Component.
My finalClick() function in One Component getting clicked but data is not going.
Save the data that you want to share in the state of Home. Pass a function from Home to Two through Two's props in order to update the data. Pass the data from Home's state down to One in the props.

How to click automatically in a button when user coming to page

import React from "react";
checkClick = () => {
console.log("clicked");
};
class Test extends React.Component {
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>
click
</button>
</div>
);
}
}
export default Test;
How to click automatically on a button when user coming to page?
Here I want to click automatically above button.
I tried with:
document.getElementById("button").click()
which does not work.
You can use a ref which gives you an instance of the dom element, where you can call the click() method.
If you aren't familiar with refs, you can read all about them here: https://reactjs.org/docs/refs-and-the-dom.html
import React, { Component } from 'react'
class Test extends Component {
constructor(props) {
super(props)
this.button = React.createRef()
}
componentDidMount() {
this.button.current.click()
}
checkClick() {
console.log('clicked')
}
render() {
return (
<div>
<button ref={this.button} onClick={this.checkClick}>Click me!</button>
</div>
)
}
}
export default Test
First of all, I do not recommend you to create functions outside of React component class. In your case, you are not able to use it like this.checkClick because the checkClick function is declared outside of your React component.
The second thing, working with real DOM inside of React is basically, let's say, antipattern. React provides virtual DOM and works with it, so, I recommend you to learn about React ref API.
For your case, you can use the lifecycle componentDidMount() method. It is being called (AUTOMATICALLY, for sure) when the component has finished its first render, so, all refs are already available here and all children elements are beind mounted and present in DOM.
import React from "react"
export default class Test extends React.Component {
componentDidMount() {
document.getElementById("button").click()
}
checkClick() {
console.log("clicked!")
}
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>click</button>
</div>
)
}
}
or, using refs
import React from "react"
export default class Test extends React.Component {
componentDidMount() {
this.button.click()
}
checkClick() {
console.log("clicked!")
}
render() {
return (
<div>
<button ref={button => this.button = button} onClick={this.checkClick}>click</button>
</div>
)
}
}
Use componentDidMount for that,
import React from 'react';
class Test extends React.Component {
componentDidMount(){
this.checkClick();
}
checkClick () {
console.log("clicked");
}
render() {
return (
<div>
<button id="button" onClick={this.checkClick}>click</button>
</div>
)
}
}
export default Test;

Resources