I'm trying to use this.state from the exported function inside the App component.
The bind method is not working. Any ideas?
I tried:
inside error-handler.js
export function errorHandler() {
console.log(this.state);
}
inside App.js
...
import { errorHandler } from '../../helpers/error-handler';
class App extends React.Component {
constructor(props) {
super(props);
this.errorHandler = errorHandler.bind(this);
}
...
The result when trying to run errorHandler() inside App.js:
"Cannot read property 'bind' of undefined"
Thank you for your help.
this.errorHandler = errorHandler.bind(this);
because you just exported function, it is not a part of your class yet
The errorHandler is just an exported function. So you have to bind the method like below.
constructor(props) {
super(props);
this.errorHandler = errorHandler.bind(this); // bind event
}
...
...
<input
{...props}
onClick={e => this.errorHandler()} // call method
/>
Related
I'm using hooks.
I have a function to use dropzone library:
export function UploadFile() {
const [files] = useState([]);
return (
<MaterialDropZone
files={files}
showPreviews
maxSize={5000000}
filesLimit={5}
text="to upload"
/>
);
}
class MyClass extends React.Component {
constructor(props) {
super(props);
this.state = {
};
}
...
render(){
return (
<UploadFile />)
}
now I want to access files inside MyClass component to uplaod my files. but I don't know how to access files.
you cannot access the state defined in child component in your parent component directly.
What you can do is that you can define files state in your parent component MyClass and pass it as props in your child component UploadFile.
In my app, I have a component with a state variable and a component variable in its constructor. However, if I try accessing them from my method by resizing the window, I get undefined and cannot read property 'test' of undefined.
import React from 'react';
class Testapp extends React.Component {
constructor(props) {
super(props);
this.state = {test: "he"};
this.test = "hu";
window.addEventListener('resize', this.testCallback);
}
testCallback() {
console.log(this.test);
console.log(this.state.test);
}
render() {
return( <p>Hello world</p> );
}
}
export default Testapp;
How can I access these attributes from the method?
Your function as is does not have access to the this variable in the correct context.
The easiest solution is to convert to an arrow function
testCallback = () => {
console.log(this.test);
console.log(this.state.test);
}
This will give your function the correct context of this.
Alternatively you could manually bind it in your constructor.
constructor(props) {
super(props);
this.state = {test: "he"};
this.test = "hu";
window.addEventListener('resize', this.testCallback);
this.testCallback = this.testCallback.bind(this);
}
Just use an arrow function instead. Alternatively, you can bind 'this' to the method.
Request.js
export default class Request extends React.Component {
getForm(e) {
let v = validator(document.getElementById('myinput')); // here is should call function from another class
}
render(){
return(
<form onSubmit={this.getForm.bind(this)}>
<RequestValidator/> // here is I called second class
<Input id="myinput" value="65"/>
</form>
}
}
}
RequestValidator.js
export default class RequestValidator extends React.Component {
validator = (e) => { // here is the target function
console.log(e.value);
}
}
What I want to do is, pass a variable (#myinput value) from Request compontent class to a function (validator) in another compontent class (RequestValidator).
What I have done so far is above codes, but I got error:
'validator' is not defined no-undef
You can do that using ref. You create one in your parent component:
class Request extends React.Component {
constructor(props) {
super(props)
this.requestValidatorRef = React.createRef();
}
then you pass it to the child component:
<RequestValidator ref={this.requestValidatorRef} />
at this point you should be able to call your method like this:
getForm(e) {
this.requestValidatorRef.current.validator(e) // ...
}
If you want to pass parameter to another class in reactjs you should use props. Also variable in requestvalidator class have to use prop name. But in your case RequestValidator and Input components are different.
In main component class call like this:
<UserInput
titles={this.state.titles}
/>
In UserInput component use this prop like this:
class UserInput extends React.Component {
componentDidMount() {
console.log(" titles from main class:", this.props.titles);
}
}
So, I try to collect the nodes after that the page are builded in the module iteamsHolder. It works for main App component and it see all collected iteams when I invoke the module iteamsHolder inside it.
But when I try to transfer the iteamsHolder module with iteams to children componennts of App, I have an error or undefined for this module iteams. So, I understand that the problem is in the component queue render. But how we can solve that error?
/* MAIN APP COMPONENT */
import iteamsHolder from '../view/iteamsHolder'
import sidebarWidgetHide from '../view/sidebarWidgetHide'
class App extends React.Component {
constructor(props) {
super(props);
this.handleKeyCode = this.handleKeyCode.bind(this);
this.handleClick = this.handleClick.bind(this);
}
render() {
return (
<Fragment>
<Preloader/>
<LeftSideInfo state={this.state.toggle} updateState={this.updateState}
coordY={this.state.coordY}/>
<MenuButtonOpen state={this.state.toggle} updateState={this.updateState}
iteamsHolder={iteamsHolder().iteamsMain}/> // this is where I'm
// trying to transfer the iteams module.
</Fragment>
)
}
/* ITEAM HOLDER MODULE */
const iteamsHolder = () => {
if (document.readyState === "complete") {
let iteamsMain = {
sidebar: document.querySelector('.left-side__column'),
rightColumn: document.querySelector('.right-side__column')
};
let iteamsSupport = {
header: document.querySelectorAll('.menu-button__container'),
menuButton: document.querySelectorAll('.menu-button'),
menuName: document.querySelector('.personal-name'),
experienceblock: document.querySelector('.block-headline.block-headline__experience')
};
return { iteamsMain, iteamsSupport };
} else {
return 'Sorry';
}
};
export default iteamsHolder;
/CHILD COMPONENT WITH NESTED ITEAMS MODULE/
class MenuButtonOpen extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.handleScroll = this.handleScroll.bind(this);
}
render() {
return (
{console.log(this.props.iteamsHolder)} // undefined of error
)
}
You're getting undefined because iteamsHolder is returning the default value 'Sorry', not the object { iteamsMain, iteamsSupport }. If you change is to:
<MenuButtonOpen
state={this.state.toggle}
updateState={this.updateState}
iteamsHolder={iteamsHolder()}
/>
you'll see that 'Sorry' is being passed to the component. This is because when iteamsHolder is being evaluated, the webpage is not yet fully loaded. Without knowing why you've structured your code the way you did, I can't make a good suggestion on how to "fix" it. What may help is looking at how document.readyState works and reading through suggestions like what's listed here.
This question already has answers here:
Unable to access React instance (this) inside event handler [duplicate]
(19 answers)
Closed 5 years ago.
Im working with a react.js app, and I remember that I was able to pass a callback function from a child to a parent with pops, the thing is I cant achieve to do this again (I'd like to keep it simple, without Flux libraries):
So my parent App:
class App extends Component {
constructor(props) {
super(props);
}
showViewAction(viewToShow){
console.log(viewToShow);
}
render() {
return (
<div>
<AppMenu showView={this.showViewAction}/>
</div>
);
}
}
And my child AppMenu:
class AppMenu extends Component{
constructor(props) {
super(props);
}
showCirculares(){
this.props.showView("circulares");
}
render(){
return(
<div>
<MenuButton onClick={this.showCirculares} buttonTitle="SomeOtherProp"/>
</div>
);
}
}
Everything I try, I always get:
Cannot read property 'props' of undefined at showCirculares;
I know this will be resolved with a simple task, and that this is basic React.js stuff, its just that I cant find a solution for this!! What am I doing wrong?
Looks like you need to bind the this context to your callback functions. Do so in the constructor function like so:
App
class App extends Component {
constructor(props) {
super(props);
this.showViewAction = this.showViewAction.bind(this);
}
showViewAction(viewToShow){
console.log(viewToShow);
}
render() {
return (
<div>
<AppMenu showView={this.showViewAction}/>
</div>
);
}
}
AppMenu
class AppMenu extends Component{
constructor(props) {
super(props);
this.showCirculares = this.showCirculares.bind(this);
}
showCirculares(){
this.props.showView("circulares");
}
render(){
return(
<div>
<MenuButton onClick={this.showCirculares} buttonTitle="SomeOtherProp"/>
</div>
);
}
}
Why? The short version is that unless you bind this, when your functions run the value of this is undefined. What you want is the context of the component instead, so you have to manually bind the functions to it.
You need to bind the showCirculares with the class so that it does not have this undefined. Following are the ways to do this.
Bind your method in constructor like this
constructor(props) {
super(props);
this.showCirculares = this.showCirculares.bind(this)
}
showCirculares(){
this.props.showView("circulares");
}
Or simply use arrow function like this
showCirculares = () => {
this.props.showView("circulares");
}
You can bind explicitly showCirculares using the bind function like #jered said, or you can use arrow functions, that are implicitly bound to the calling this.
<MenuButton onClick={() => this.showCirculares()} buttonTitle="SomeOtherProp"/>