I am trying to use the useContext from preact. It seems I am doing something wrong, because my Context give undefined values.
Here is the main file:
const {render, h, createContext} = window.preact
import htm from 'https://unpkg.com/htm?module'
const html = htm.bind(h)
import SampleComp from './sample-comp.js'
export const ContextOne = createContext()
export const ContextTwo = createContext()
const RootComp = (props) => {
return html`
<ContextOne.Provider value=${'ContextOne'}>
<ContextTwo.Provider value=${'ContextTwo'}>
<${SampleComp}/>
</ContextTwo.Provider>
</ContextOne.Provider>
`
}
render(html`<${RootComp} />`, document.body);
and here is the sample component:
const {useContext} = window.preactHooks
const {h} = window.preact
import htm from 'https://unpkg.com/htm?module'
const html = htm.bind(h)
import {ContextOne, ContextTwo} from './index.js'
export default function SampleComp (props) {
const one = useContext(ContextOne)
const two = useContext(ContextTwo)
return html`<div>${one} - ${two}</div>`
}
What am I doing wrong here? I have been trying to figure it out for a few hours now but no idea.
I got it.
Just after posting the question I realized that by using htm I need to wrap the providers in the template string to be a variable. so correct would be:
const RootComp = (props) => {
return html`
<${ContextOne.Provider} value=${'ContextOne'}>
<${ContextTwo.Provider} value=${'ContextTwo'}>
<${SampleComp}/>
</ContextTwo.Provider>
</ContextOne.Provider>
`
}
Related
where is the error and what should need to change can you explain. After the cart.map props can not read the property name and others. it just read it as an array . when i do console.log(props.product) then in console tab show all added product but when i want to read the name,price and others it cannot it just read only quantity.
i added picture of the console tab please check it.
now what is the problem of that code
please help me out
**Review.js
**
import React, { useEffect, useState } from 'react';
import { getDatabaseCart } from '../../utilities/databaseManager';
import fakeData from '../../fakeData';
import ReviewItem from '../ReviewItem/ReviewItem';
import Cart from '../Cart/Cart';
const Review = () => { const [cart, setCart] = useState([]);
useEffect(()=>{
//cart
const savedCart = getDatabaseCart();
const productKeys = Object.keys(savedCart);
const cartProducts = productKeys.map( key => {
const product = fakeData.filter( pd => pd.key === key);
product.quantity = savedCart[key];
return product;
});
setCart(cartProducts);
}, []);
return (
<div className="twin-container">
<div className="product-container">
{
cart.map(pc => <ReviewItem
key={pc.key}
product={pc}></ReviewItem>)
}
</div>
</div>
);
};
export default Review;
reviewItem.js
import React from 'react';
const ReviewItem = (props) => {
const {name,price,quantity} = props.product;
const reviewItemStyle={
borderBottom:'1px solid lightgray',
marginBottom:'5px',
paddingBottom:'5px',
marginLeft:'200px'
};
console.log(name);
return (
<div style={reviewItemStyle} className="review-item">
<h4 className="product-name">Name:{name}</h4>
<p>Quantity: {quantity}</p>
<p><small>$ {price}</small></p>
<br/>
</div>
);
};
export default ReviewItem;
I am trying to access state from one component to another
FetchCompo.js
// import React from "react";
import React, { useState, useEffect } from "react";
//more imports
const FetchUserItems= () => {
//some state
const [userFirstName, setUserFirstName] = useState("");
const [userItem, setUserItem] = useState([]);
let userName = //somecode
setUserFirstName(userName);
let userItemsData= userData.MyArray.items;
if (userItemsData.length === 0) {
const emptyItems = [
{
//obj data
},
];
setUserItem(emptyItems );
} else {
//someData
setUserItem(userItemsData);
}
return { userFirstName, userItem};
};
export default FetchCompo;
I wanted to use userFirstName, userItem in the another Test.js component.
// import React from "react";
import React, { useState, useEffect } from "react";
import FetchCompofrom "../myFunctions/FetchCompo";
//more imports
const Test = () => {
//Wanted to use userFirstName in Test.js component
const { userFirstName, userItem } = FetchCompofrom();
return (
<div>{userFirstName}</div>
)
}
when I am trying to get the userFirstName, userItem in the Test.js component then getting error of Too many renders
looking for a solution how i can access these state userFirstName, userItem form one component to another.
You're actually importing the React Component not the FetchUserItems helper function...
import FetchCompofrom "../myFunctions/FetchCompo";
But you could do something like...
const [userFirstName, setUserFirstName] = useState('');
const [userItem, setUserItem] = useState([]);
const FetchUserItems = () => {
/**
* Make it plain helper function for fetching userItems
* Do-not set-state here...
*/
return { userFirstName, userItem };
};
export const FetchUserItems;
/** In your component ... say in useEffect */
const result = FetchUserItems();
/** setState here in case of result */
In Test.js
import { FetchUserItems } "../myFunctions/FetchCompo";
Your are using setUserFirstName(userName) in FechUserItems, outside useEffect or normal function, this will provoque the component to re-render indefinitely because setting the states provoques re-rendering.
I would suggest to make FetchUserItems a normal function, because you are not rendering anything in it. You could use only Test comp for it.
The Test comp would be something like this:
// import React from "react";
import React, { useState, useEffect } from "react";
import FetchCompofrom "../myFunctions/FetchCompo";
//more imports
const Test = () => {
const [userFirstName, setUserFirstName] = useState("");
const [userItem, setUserItem] = useState([]);
useEffect(() => fetchUserFirstName, [])
const fetchUserFirstName = () => {
// your code here and
// setUserFirstName in the end
}
//Wanted to use userFirstName in Test.js component
const { userFirstName, userItem } = FetchCompofrom();
return (
<div>{userFirstName}</div>
)
}
I try to use Xtermjs in Reactjs. but when I follow the guide. the result shows as following:
It should show without top textarea and text 'W'.
My codes is as following:
import React from 'react';
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
class XTerminal extends React.Component {
componentDidMount() {
const {id} = this.props;
const terminalContainer = document.getElementById(id);
const terminal = new Terminal({cursorBlink: true});
const fitAddon = new FitAddon();
terminal.loadAddon(fitAddon);
terminal.open(terminalContainer);
terminal.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ');
fitAddon.fit();
}
render() {
return(
<div id={this.props.id}></div>
)
}
}
export default XTerminal;
I seach a similar question in stackoverflow without no answer. and I cannot comment in that question. So I write this question. Could anyone help? thanks :)
Finally I got this. For those who have this problem. you should import xterm css style file. like following:
import React from 'react';
import { Terminal } from 'xterm';
import './xterm.css';
import { FitAddon } from 'xterm-addon-fit';
class XTerminal extends React.Component {
componentDidMount() {
const {id} = this.props;
const terminalContainer = document.getElementById(id);
const terminal = new Terminal({cursorBlink: true});
const fitAddon = new FitAddon();
terminal.loadAddon(fitAddon);
terminal.open(terminalContainer);
terminal.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ');
fitAddon.fit();
}
render() {
return(
<div id={this.props.id}></div>
)
}
}
export default XTerminal;
I'm trying my hand at TypeScript and React. I have a functional component (code below) that is supposed to consume a context with useContext, but it is showing me this weird error that I cannot find a solution to.
If I do not use TS, and go with JSX, it works just fine.
Edit: Screenshot>
Code:
AppProvider.tsx
import React, { useState, useEffect } from "react";
// Application's context (for general application-wide usage)
const AppContext: any = React.createContext(null);
// this will be used below in the componet we will export
export const AppContextProvider = AppContext.Provider;
export const AppProvider: React.FC = (props: any) => {
const [appName, setAppName] = useState("Blood Donation");
const [appUser, setAppUser]: any = useState(null);
const [appInfoBusy, setAppInfoBusy] = useState(false); // working to get or set data
useEffect(() => {
getAppInfo();
}, []);
const getAppInfo = () => {
setTimeout(() => {
setAppName("Test");
setAppUser({
name: "Admin",
email: "test#test.com",
role_id: 100
});
}, 3000);
};
return (
<AppContextProvider
value={{
appName: appName,
appInfoBusy: appInfoBusy,
appUser: appUser
}}
>
{props.children}
</AppContextProvider>
);
};
Consumer: Login.tsx
import React, { useState, useEffect, useContext } from "react";
import {
Button,
Card,
Elevation,
FormGroup,
InputGroup,
Drawer,
Classes,
H4,
Callout,
H5
} from "#blueprintjs/core";
//#ts-ignore
import ReCAPTCHA from "react-google-recaptcha";
import logo from "../../assets/images/logo.png";
import "../../scss/Login.scss";
import { RecaptchaKey } from "../../shared/Info";
import { AppContextProvider } from "../../shared/context/AppProvider";
const Login: React.FC = props => {
const [email, setEmail]: React.ComponentState = useState();
const [password, setPassword]: any = useState();
const [isOpen, setIsOpen]: any = useState();
const [resetEmail, setResetEmail]: any = useState();
const [emailSent, setEmailSent]: any = useState();
const [captchaOk, setCaptchaOk]: any = useState(false);
const [working, setWorking]: any = useState(false);
// context
const { appName, appUser, appInfoBusy } = useContext(AppContextProvider);
/**
* Handles lifecycle hooks
*/
useEffect(() => {
// when component is mounted
}, []);
/**
* Handles Captcha change
* #param value
*/
const recaptchaChange = (value: any) => {
setCaptchaOk(value ? true : false);
};
const handleRecoverySubmit = () => {
setWorking(true);
setTimeout(() => {
setEmailSent(true);
setWorking(false);
}, 3000);
};
return (
<div id="loginPage">
... removed for brevity ...
</div>
);
};
export default Login;
Any help is gratefully thanked. React and dependencies are all latest as of date.
I was using the context provider instead of the context itself inside useContext(), I should have used useContext(AppContext) instead.
Commentary removed because stackoverflow.
The error is _useContext not defined. The issue is different than what it is actually referring to.
you created a context called as AppContext
and then you export this as
export const AppContextProvider = AppContext.Provider;
You have done correct till this stage.
The problem lies at consumer part i.e. login.tsx file.
you are importing a name file inside a curly braces which is not correct, because the context is exported as a name variable. You simply need to write
import AppContextProvider from "../../shared/context/AppProvider";
That's it, and when you are calling this context using useContext hooks, then the actual state that you are looking for get accessed and no issue will further persist.
Note: Don't use {} for importing named exports.
reference: When should I use curly braces for ES6 import?
I am having difficulty using refs with Styled Components. When I try to access them in my class methods like below, I get the following error:
Edit.js:42 Uncaught TypeError: this.....contains is not a function
constructor(props) {
....
this.setWrapperRef = this.setWrapperRef.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
}
----------
setWrapperRef = (node) => {
this.wrapperRef = node;
}
handleEdit = (e) => {
e.preventDefault();
this.props.onEdit(this.props.id, this.state.title);
}
----------
<Wrapper onSubmit={this.handleEdit} ref={this.setWrapperRef}>
...
</Wrapper>
I found the code from this question
What am I doing wrong here?
I found the answer myself. The solution is to use innerRef instead of ref as the ref itself points to the Styled Component and not the DOM node.
A detailed discussion can be found on GitHub
If you extend another component in styled ref forwarding requires efford. so my solution was extending that component with as prop.
before:
import { useRef } from 'react'
import styled from 'styled-components'
const Card = styled.div``
const Block = styled(Card)``
const Component = () => {
const ref = useRef(null);
return <Card ref={ref} />
}
after:
import { useRef } from 'react'
import styled from 'styled-components'
const Card = styled.div``
const Block = styled.div``
const Component = () => {
const ref = useRef(null);
return <Block as={Card} ref={ref} />
}
const StyledComponent = styled.div.attrs(({ref}) => ({
ref: ref,
}))``
const App = () => {
const anyRef = useRef();
return <StyledComponent ref={anyRef}/>
};