I am using react-dom#16.6.1 and react#16.6.1 that should support react Context and trying to run a simple example same as the react-context:
app.js
import React, { Component } from 'react';
import AppManger from './components/AppManger';
import './App.css';
export const ThemeContext = React.createContext({a1:'a1'});
class App extends Component {
render() {
return (
<div className="App">
<h1>Manage Storefront Services Products</h1>
<ThemeContext.Provider value="dark">
<AppManger />
</ThemeContext.Provider>
</div>
);
}
}
export default App;
AppManger.js(has no context reference)
import React, { Component } from 'react'
import SearchBar from './SearchBar';
export default class AppManger extends Component {
constructor(props) {
super(props);
this.onSearchBarChange = this.onSearchBarChange.bind(this);
this.state = {
searchValue: '',
errorLoading: false,
errorObj: null,
}
}
onSearchBarChange(e) {
e.persist();
this.setState({ searchValue: e.target.value });
}
render() {
return (
<div>
Log out
<SearchBar onSearchBarChange={this.onSearchBarChange} inAttrView={this.state.onAttrPage} />
</div>
)
}
}
And the SearchBar.js where I want to use Context:
import React, { Component } from 'react';
import ThemeContext from '../App';
export default class SearchBar extends Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
showAttrModal: false
};
};
componentDidMount(){
console.log(this.context); //{}
}
render() {
const contextType = ThemeContext;
console.log(contextType); //{}
return (
<div>
{contextType} /*'contextType' is not defined no-undef */
<input type="text" style={searchBoxStyle} className="form-control" onChange={this.props.onSearchBarChange} placeholder="Search for..." id="sku" name="sku" />
</div>
)
}
}
If I run the app I get Line 44: 'contextType' is not defined no-undef in SearchBar.js if I remove this line I get {} when I logging the this.context.
You aren't correctly using context, as you need to define it as a static property of the class and import it as a named import since you have exported it as a named import
import { ThemeContext } from '../App';
export default class SearchBar extends Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
showAttrModal: false
};
};
static contextType = ThemeContext;
componentDidMount(){
console.log(this.context); //{}
}
render() {
console.log(this.contextType); //{}
return (
<div>
{contextType} /*'contextType' is not defined no-undef */
<input type="text" style={searchBoxStyle} className="form-control" onChange={this.props.onSearchBarChange} placeholder="Search for..." id="sku" name="sku" />
</div>
)
}
}
You imported App instead of ThemeContext.
use import { ThemeContext } from '../App.js;
Here problem:
componentDidMount() {
console.log(this.context);
}
Here can't find this.context variable.
static contextType =
To
const contextType =
Related
I'm working on todo app in React and I have weird problem. I created onClick effect on trash icon to remove whole task component. The thing is, sometimes it works (removes whole task), sometimes not (removes only icon). I tried different solutions but to be honest I have no idea why it works like this, this is the same script working differently in different components, for some reason.
main component:
import React from 'react'
import TaskContainer from './TaskContainer.js';
import SingleTask from './SingleTask'
class AppContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
children: [],
numChildren: 0,
newMessage: "What to do next?"
}
this.onAddChild = this.onAddChild.bind(this)
this.handleChange = this.handleChange.bind(this)
}
onAddChild = (msg) => {
let newArray = this.state.children.concat(<SingleTask message={msg} />);
this.setState({ children: newArray });
console.log(this.state.children)
}
handleChange(event) {
this.setState({ newMessage: event.target.value })
}
render() {
return (
<div className="app-container">
<div className="new-task-container">
<input type="text" id="taskInput" defaultValue="What to do next?"
maxlength="50" onChange={this.handleChange} />
<div className="addTask" id="addTask" onClick={
() => {
let text = document.getElementById("taskInput").value;
this.setState({ newMessage: text })
this.onAddChild(this.state.newMessage);
}
}>
<div className="add-button">Add task</div>
</div>
</div>
<TaskContainer>
{this.state.children}
</TaskContainer>
</div>
)
}
}
export default AppContainer
child component
import SingleTask from './SingleTask.js';
function TaskContainer(props) {
return (
<div className="task-container">
{props.children}
</div>
)
}
export default TaskContainer
child's child component - SingleTask
import React from 'react'
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faTrashAlt } from '#fortawesome/free-regular-svg-icons'
class SingleTask extends React.Component {
constructor(props) {
super(props)
this.state = { active: true }
}
render() {
return (
<div className="singleTask" >
<p>{this.props.message}</p>
<div className="removeTask" onClick={(event) => {
setTimeout(() => {
event.target.parentNode.parentNode.remove()
}, 350)
}
}>
<FontAwesomeIcon icon={faTrashAlt} />
</div>
</div>
)
}
}
export default SingleTask
thanks in advance
I create a CodeSandbox with all the necessary corrections.
https://codesandbox.io/s/upbeat-jang-v7jvm
Piece of advice: When using React is not recommend that you modify the DOM by yourself.
I'm new to react and I'm getting an error for the state and method:
./src/App.js
Line 5: 'state' is not defined no-undef
Line 8: 'inputchangehandler' is not defined no-undef
This is my code until now:
import React from 'react';
import './App.css';
function App() {
state = {
userInput: ''
}
inputchangehandler = (event) => {
this.setState = ({
userInput: event.target.value
})
}
return (
<div className="App">
<input type="text" name="name"
onChange={this.inputchangehandler}
value = {this.state.userInput}/>
</div>
);
}
export default App;
In react there are 2 types of components.
Functional Components(like you used)
Class Components
Functional Components are stateless(in older versions, you can use hooks now) components. So if you want to directly use state you should change your components to class based component like this:
import React, { Component} from 'react';
import './App.css';
class App extends Component {
state = {
userInput: ''
}
inputchangehandler = (event) => {
this.setState = ({
userInput: event.target.value
})
}
render(){
return (
<div className="App">
<input type="text" name="name"
onChange={this.inputchangehandler}
value = {this.state.userInput}/>
</div>
);
}
}
export default App;
Functional component don't have state, form React 16.8 we have Hooks.
You should use useState hook for state.
import React, {useState} from 'react';
const [userInput, setUserInput] = useState('')
Usage,
<input type="text" name="name"
onChange={inputchangehandler}
value = {userInput}/>
inputchangehandler function should be,
const inputchangehandler = (event) => {
setUserInput(event.target.value)
}
Demo
Note: Functional component don't have access to this.
You have created functional component which does not have state. Define App as class component like below :
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
userInput: ''
}
}
inputchangehandler = (event) => {
this.setState = ({
userInput: event.target.value
})
}
render() {
return (
<div className="App">
<input type="text" name="name"
onChange={this.inputchangehandler}
value={this.state.userInput} />
</div>
);
}
}
export default App;
You need to define state in your class's constructor like below:
constructor(props) {
super(props);
this.state = {
userInput: ''
}
}
Declaring your component as a function you don't have state.
Try converting it in class component or in a function using Hooks according to react documentation.
If you are using React version greater than 16.8 then you can use the useState hook.
import React from 'react';
import './App.css';
function App() {
const [userInput, setUserInput] = useState(0);
inputchangehandler = (event) => {
setUserInput(event.target.value)
}
return (
<div className="App">
<input type="text" name="name"
onChange={this.inputchangehandler}
value = {userInput}/>
</div>
);
}
export default App;
Refer: https://reactjs.org/docs/hooks-state.html
If you are using an older version then you will need to convert it to a React.Component
If you don't want to write a class component, you should use hooks, so your code will be like this:
import React, { useState } from 'react';
import './App.css';
function App() {
const [userInput, setUserInput] = useState(undefined);
inputchangehandler = (event) => {
setUserInput(event.target.value)
}
return (
<div className="App">
<input type="text" name="name"
onChange={this.inputchangehandler}
value = {userInput}/>
</div>
);
}
export default App;
i was on React version 17 this worked for me for state undefined error:
Adding example from React official docs:
class Clock extends React.Component { constructor(props) {
super(props);
this.state = {date: new Date()}; }
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
); } }
Assuming you're working with a class component rather than a functional component (as mentioned in other answers), the error state is not defined can occur if you forgot to prefix it with this..
Instead of:
myFunction() {
let myVariable = state.myStateKey;
// ...
}
Do:
myFunction() {
let myVariable = this.state.myStateKey;
// ...
}
I'm trying to use a function, which is in a different component from App.js.
and I'm having the syntax error, I don't know what did I do wrong. I have a button in App.js and when I click on it, that function from another component that I've mentioned earlier should trigger.
app.js:
import React from 'react';
import {shaking} from './components/Tree/Tree.js';
class App extends React.Component {
constructor() {
super();
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
shaking();
console.log("done !");
}
render() {
return (
<div>
<Tree className='tree' />
<Apples />
<Basket />
<br/>
<button className="start-btn" onClick={this.handleClick}>Start !</button>
<br/>
</div>
);
}
};
export default App;
And this is my another component:
import React from 'react';
import TreeSvg from './Tree-svg/TreeSvg.js';
import './Tree.sass';
export function shaking(){
const tree = document.getElemenetsByClassName(".tree-img")[0];
tree.classList.add("apply-shake");
console.log('shaked!');
}
class Tree extends React.Component{
constructor() {
super();
this.shaking = this.shaking.bind(this);
}
shaking() {
this.setState({shaked:'1'});
const tree = document.getElemenetByClassName(".tree-img");
tree.classList.add("apply-shake");
console.log('shaked!');
}
render(){
return(
<div className="tree-img">
<TreeSvg />
</div>
);
}
};
export default Tree;
Make your Tree component like this
import React from 'react';
import TreeSvg from './Tree-svg/TreeSvg.js';
import './Tree.sass';
export function shaking(){
const tree = document.getElementsByClassName(".tree-img")[0];
tree.classList.add("apply-shake");
console.log('shaked!');
}
class Tree extends React.Component{
constructor() {
super();
this.state = {
shaked : ''
}
shaking() {
this.setState({shaked:'1'});
const tree = document.getElementByClassName(".tree-img");
tree.classList.add("apply-shake");
console.log('shaked!');
}
render(){
return(
<div className="tree-img">
<TreeSvg />
</div>
);
}
};
export default Tree;
You do have 2 syntax errors in your code. Both are located at the Tree component file.
At your exported function (Line 6):
const tree = document.getElemenetsByClassName(".tree-img")[0];
replace Elemenets with Elements.
At the class method shaking() (Line 21):
const tree = document.getElemenetByClassName(".tree-img"); replace Elemenet with Element
How to access the state variable testState from the different class UserAuthentication?
I have tried this without success:
import React from 'react';
import UserAuthenticationUI from './UserAuthentication/UserAuthenticationUI';
class App extends React.Component {
constructor(props) {
super(props);
this.userAuthenticationUI = React.createRef();
this.state={
testState: 'test message'
}
}
render() {
return(
<div>
<UserAuthenticationUI ref={this.userAuthenticationUI} />
<div>
)
}
}
export default App;
How to access this.state.teststate from class UserAuthenticationUI?
import React from "react";
import App from '../App';
class UserAuthenticationUI extends React.Component {
constructor(props) {
super(props);
this.app = React.createRef();
}
render() {
return(
<div>
<App ref={this.app} />
{console.log(this.state.testState)}
</div>
)
}
}
export default UserAuthenticationUI;
You need to pass it via props.
import React from "react";
import UserAuthenticationUI from "./UserAuthentication/UserAuthenticationUI";
class App extends React.Component {
constructor(props) {
super(props);
this.userAuthenticationUI = React.createRef();
this.setParentState = this.setParentState.bind(this);
this.state = {
testState: "test message"
};
}
setParentState(newStateValue){ // this is called from the child component
this.setState({
testState: newStateValue
})
};
render() {
return (
<div>
<UserAuthenticationUI
stateVariable={this.state.testState}
ref={this.userAuthenticationUI}
setParentState={this.setParentState}
/>
</div>
);
}
}
export default App;
UserAuthenticationUI:
import React from "react";
import App from "../App";
class UserAuthenticationUI extends React.Component {
constructor(props) {
super(props);
this.app = React.createRef();
this.onClick = this.onClick.bind(this);
}
onClick(){
const newStateValue = 'new parent state value';
if(typeof this.props.setParentState !== 'undefined'){
this.props.setParentState(newStateValue);
}
}
render() {
const stateProps = this.props.stateVariable;
return (
<div>
<App ref={this.app} />
<div onClick={this.onClick} />
{console.log(stateProps)}
</div>
);
}
}
export default UserAuthenticationUI;
You should think differently.
Try to read the variable via GET methods and set via SET methods.
Do not try to call the variable immediately
Hope this helps.
you can pass it through Props:
import React from 'react';
import UserAuthenticationUI from
'./UserAuthentication/UserAuthenticationUI';
class App extends React.Component {
constructor(props) {
super(props);
this.userAuthenticationUI = React.createRef();
this.state={
testState: 'test message'
}
}
render(){
return(
<div>
<UserAuthenticationUI testState={this.state.testState} />
<div>
)}
}
export default App;
UserAuthenticationUI:
import React from "react";
import App from '../App';
class UserAuthenticationUI extends React.Component
{
constructor(props){
super(props);
}
render(){
return(
<div>
<App/>
{console.log(this.props.testState)}
</div>
)}
}
export default UserAuthenticationUI;
You can access it via props:
<div>
<UserAuthenticationUI testState={this.state.testState} ref={this.userAuthenticationUI} />
<div>
and in UserAuthenticationUI class access it:
<div>
<App ref={this.app} />
{console.log(this.props.testState)}
</div>
having a serious challenge with my React/Redux authorization setup and I'm at a loss. Current error is:
HomeHeader.js?8595:26 Uncaught ReferenceError: dispatch is not defined
There's a lot wrong here, and any help would be appreciated.
I'm creating two authorization components, one to register and one to login. The AuthorizationLogin component is what I'm working on first.
I don't know how to get this to pass the event info it grabs form the form fields, put in the variable creds, and then on up through the HomeHeader component, and then again up to the HomePage container. Do I put all of the authorization components into one enormous HomeHeader component?
Here's the main code and flow. Code isn't loading right into StackOverflow for some reason.
HomePage.js
import React from 'react';
import {connect} from 'react-redux';
import * as actions from '../../../actions/homeEventFormActions';
import HomeHeader from '../homeHeader/HomeHeader';
import HomeEventForm from '../homeEventForm/HomeEventForm';
class HomePage extends React.Component {
constructor(props) {
super(props);
}
render() {
const { dispatch } = this.props;
return (
<div>
< HomeHeader />
< HomeEventForm
onSubmit={this.props.onSubmit}
/>
</div>
);
}
}
function mapStateToProps(state) {
return {
homeEventForm: state.homeEventForm
};
}
function mapDispatchToProps(dispatch) {
return {
onSubmit: (eventName) => dispatch(actions.createEventButton(eventName)),
};
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(HomePage);
HomeHeader.js
import React, { Component, PropTypes } from 'react';
import AuthorizeLogin from '../../Authorization/AuthorizeLogin';
import AuthorizeRegister from '../../Authorization/AuthorizeRegister';
import { loginUser } from '../../../actions/authorizationActions';
class HomeHeader extends React.Component {
constructor() {
super();
}
_handleChange(eventKey) {
...
<AuthorizeLogin
onLoginClick={ (creds) => dispatch(loginUser(creds))}
/>
...
}
return;
}
render() {
const { dispatch } = this.props;
return (
...
<Modal.Header closeButton onClick={ ()=> this._handleChange(5)}>
...
);
}
}
export default HomeHeader;
AuthorizeLogin.js
import React from 'react';
class AuthorizeLogin extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {};
this._login = this._login.bind(this);
}
_login(e) {
e.preventDefault;
const email = this.refs.email;
const password = this.refs.password;
const creds = { email: email.value.trim(), password: password.value.trim() };
this.props.onLoginClick(creds);
}
render() {
return (
<Form horizontal onSubmit={this._login}>
<h4 className="authEmailText">Login with your email</h4>
<input type="email" placeholder="urawesome#example.com" ref='email' />
<input type="password" placeholder="Password" ref='password' />
</Form>
);
}
}
export default AuthorizeLogin;
All the actions should be dispatched from container. In this case, the container should have the dispatch.
function mapDispatchToProps(dispatch) {
return {
onSubmit: (eventName) => dispatch(actions.createEventButton(eventName)),
onLogin: (creds) => dispatch(loginUser(creds)),
};
}
The onLogin should be passed to downstream components via props:
<HomeHeader onLogin={this.props.onLogin} />
<AuthorizeLogin
onLoginClick={this.props.onLogin}
/>