Define Functions for OnClick in React Component with ES6 Syntax - reactjs

I currently structure my React Components the following:
export default class Heading extends Component {
render() {
return (
<h1 onClick={changeLanguage("en_US")}>I am a Heading!</h1>
);
}
}
And now after some research I haven't found any way to define functions inside the Component Class that can be used inside the onClick attribute of something.
Everything I found was only for React.createClass or something like that.

You should be able to define the method inside of your component. You will need to wrap your event handler so you can pass an argument to it
export default class Heading extends Component {
changeLanguage(lang){
}
render() {
return (
<h1 onClick={()=>this.changeLanguage("en_US")}>I am a Heading!</h1>
)}

If the function is outside the render, you would refer to it like so:
export default class Heading extends Component {
changeLanguage = () => {
//do something
}
render() {
return (
<h1 onClick={()=>this.changeLanguage("en_US")}>I am a Heading!</h1>
);
}
}
changeLangue needs to be an arrow function to maintain context.

Related

Is it possible to render inside a functional component in reactjs?

I want to know the proper method to use render(){} while I'm using the functional component.
i'm new on reactjs, so far i'm always using functional component on everything :
const Something = () => {
}
export default Something
What i want is to render object which is react-scroll-parallax, while i'm using functional component, but i don't know the proper method to do that :
const Something = () => {
render() {
return (
<ParallaxProvider>
<Parallax className="custom-class" y={[-20, 20]} tagOuter="figure">
<ImageBg src="../../images/wpbatik.jpg" />
</Parallax>
</ParallaxProvider>
);
}
}
export default Something
Thank you
In a functional component, you use return and it will work the same way as return inside of the render() {} function in a class-based component.
Example:
function App() {
return(
<div>Some stuff inside</div>
)
}
Here's a class based version of it:
class App extends React.Component {
render() {
return <div>Some stuff inside</div>;
}
}

How can I use the function of one component in another component? (react)

I want to use a function setCount() in the class Footer in another component. But I get an error that I do not know why.
class Footer:
export default class Footer extends Component {
setCount()
{
//code
}
render() {
return (
<div >
//code
</div>
);
}
}
class TodoItem:
import footer from "./Footer"
#observer
class TodoItem extends Component {
ontoggle=()=>{
this.props.todo.toggle();
footer.setCount() //this line get an error
}
render(){
const {todo} =this.props
return(
//code
)
}
}
type error: TypeError: _Footer__WEBPACK_IMPORTED_MODULE_8__.default.setCount is not a function
How can I fix it?
You can make setCount method as static in order to make it work. However, a static method cannot access this keyword.

React - What is meant by 'Do not use HOC’s in the render method of a component. Access the HOC outside the component definition.'?

I am learning HOCs and keep reading the above quote, but I do not understand what it means. If my HOC adds a method to my consuming component, can I use that method in the render method like so? If not how would I do what I am trying to do here:
import React, { Component } from 'react';
import { withMyHOC } from '../with_my_component'
class MyComponent extends Component {
constructor(props) {
super(props);
}
render() {
const { methodFromHOC }= this.props;
const result = methodFromHOC(someArgument);
return (
<div >
{result}
</div>
)
}
}
export default withMyHOC(MyComponent );
When you say, do not use HOC within the render method, it means that you shouldn't create an instance of the component wrapped by HOC within the render method of another component. For example, if you have a App Component which uses MyComponent, it shouldn't be like below
import React, { Component } from 'react';
class MyComponent extends Component {
constructor(props) {
super(props);
}
render() {
const { methodFromHOC }= this.props;
const result = methodFromHOC(someArgument);
return (
<div >
{result}
</div>
)
}
}
export default MyComponent;
import { withMyHOC } from '../with_my_component'
export default class App extends React.Component {
render() {
const Wrap = withMyHOC(MyComponent);
return (
<div>
{/* Other Code */}
<Wrap />
</div>
)
}
}
Why you shouldn't use it like above is because everytime render method is called a new instance of the MyComponent is created wrapped by HOC called Wrap and hence everytime it be be mounted again instead of going by the natural lifecycle or React.
However if your HOC passes a function as props, you can use it within the render as long as it doens't cause a re-render again otherwise it will lead to a infinite loop.
Also its better to memoize functions which are called in render directly to avoid computation again and again
CodeSandbox Demo
A High Order Component is a function which returns a Component, not jsx. When wrapping a component with an hoc, you're not changing the returned value of your component, you're changing the signature itself. Consider the following hoc
const withFoo = Component => props =>{
return <Component {...props} foo='foo' />
}
withFoo is a function which takes a Component (not jsx) as argument and returns a component. You don't need to call an hoc from render because the values it injects are already inside props of the wrapped component.
An hoc tells how a wrapped component will look like, changes it's definition so the only place to use it is in the component definition itself. Calling an hoc inside render creates a new instance of that component on each render. It's the equivalent of
const Component = () =>{
const ChildComponent = () =>{
return <span> Child </span>
}
return <ChildComponent /> //You're declaring again on each render
}
Use your high order components like this
const Component = ({ foo }) => <div>{ foo }</div>
export default withFoo(Component)
Or
const Component = withFoo(({ foo }) => <div>{ foo }</div>)

Pass event through nested components bottom to top

While this question has been asked before I did not find an answer. I have components nested to the level of great grandchild and I don't know how to get the data from the bottom to the top.
<Parent/>
<Child/>
<GrandChild/>
<GreatGrandChild/>
See an example: fiddle
The great grandchild is a form and I want the input data to get to the parent at the top. I had it working when it was just nested one level deep, but now that it is deeply nested it does not work. I'm not sure how to even pass the event up two levels.
I've heard using redux is possible but I wonder if there is a way to avoid it. Or, how do I avoid the nesting? Even through they are all actually separate components should I just move them into one big component? This might work but seems like bad practice?
Very simplified, you could just pass the function through all the components:
class GreatGrandChild extends React.Component {
render() {
return (
<div>
<input onChange={this.props.onChange}/>
<h2>I'm the GreatGrandChild</h2>
</div>
)
}
}
class GrandChild extends React.Component {
render() {
return (
<div>
<h2>I'm the GrandChild</h2>
<GreatGrandChild onChange={this.props.onChange}/>
</div>
)
}
}
class Child extends React.Component {
render() {
return (
<div>
<GrandChild onChange={this.props.onChange}/>
<h2>I'm the child</h2>
</div>
)
}
}
class Top extends React.Component {
constructor(props) {
super(props)
this.state = {
}
}
handleChildchange = (e) => {
console.log('child event on parent')
console.log(e.target.value);
}
render() {
return (
<div>
<Child onChange={this.handleChildchange}/>
<h2>I'm the parent</h2>
</div>
)
}
}
ReactDOM.render(<Top />, document.querySelector("#app"))
Redux is overkill for simple passing of props. You can pass props down through each child but it's easier to use the Context API like so:
Parent Component:
const MyContext = React.createContext('default');
export MyContext;
class Parent extends React.Component {
myFunction() {
//Do something here
}
render() {
return (
<MyContext.Provider value={this.myFunction}>
<ChildComponent />
</MyContext.Provider>
);
}
}
export default Parent;
Child Component:
import { MyContext } from './Parent';
class ChildComponent extends React.Component {
render() {
const { myFunction } = this.context;
return (
<div onClick={myFunction}>Click Me!</div>
);
}
}
ChildComponent.contextType = MyContext;
You can use the context as deep as you'd like, as long as you import it.
Simply pass a callback down from the parent via the props and make Sure it's passed all the way down to where you need it.
You also can pass props to your each child component in nesting and whenever values changed, you can call a parent function (nested) to get latest values in parent.

React. how to pass props from onClick to function

I am new to React, I am trying to create an app in which I can click on a button and a function will run countdown timer, but If I pass props from onClick to begin function like this, onClick={begin(props.subject)} the function will run before I click. and if I use onClick with begin without argument, there is no props being passed down. how can I fix that? thanks
import React from 'react';
import SubjectForm from './SubjectForm';
const EditSubject=(props)=>{
return(
<div>
<button onClick={begin}>start</button>
</div>)
};
const begin = (props)=> {
console.log(props.subject)
}
const mapStateToProps=()=>{};
export default connect(mapStateToProps)(EditSubject);
also, is there a way or trick to use a variable inside of begin function from an outside function? so I can make a pause button to pause seInterval in begin function.
You are using functional (stateless) components in this example. You can also use ES6 classes to represent React components, with functions being methods of the class. Then you may make functions like begin in your code as class methods, so they can access class data members like props.
See the code below:
import React from 'react';
import SubjectForm from './SubjectForm';
class EditSubject extends React.Component {
constructor() {
super();
this.begin = this.begin.bind(this);
}
begin() {
console.log(this.props.subject);
}
render() {
return (
<div>
<button onClick={begin}>start</button>
</div>
);
}
};
const mapStateToProps=()=>{};
export default connect(mapStateToProps)(EditSubject);
This is just a best practice if your component has states, and methods. Using functional components like in your example, you may use simply the following:
const EditSubject = (props) => {
return (
<div>
<button
onClick={() => begin(props)} // using props here
>
start
</button>
</div>
);
};
Simple, right ?

Resources