Access form elements of wrapped component in HOC? - javascript

I want to build an HOC, in which i want to access the form elements present in the Wrapped Component.
import React from 'react';
const hoc = (WrappedComponent) => (props) => {
return(
<React.Fragment>
<WrappedComponent { ...props }></WrappedComponent>
</React.Fragment>
)
};
export { hoc };
In this HOC, i want access each element from the WrappedComponent. Can anyone guide me the way to implement this functionality

Related

adding class or hooks inside app component

i'm new to react world, in react sites it says that hooks cannot be used inside class, my question is for example i have app.js can i have components inside it which are class based and also functional (hooks) ? for example in this App.js can 'NavBar' be functional (hooks) component and 'Page' be class component or can those have inside them class/hooks components ?
const store = configureStore({});
const Loader = () => (
<div className="App">
<div>loading...</div>
</div>
);
const theme = createMuiTheme({
palette: {
primary: yellow
secondary: black
action: {
selected: orange[600],
},
},
status: {
danger: 'ooooo',
},
});
const TranslatedApp = () => {
const { t } = useTranslation();
return (
<Provider store={store}>
<ConnectedRouter history={hist}>
<NavBar siteName={t('siteN')} />
<Page />
</ConnectedRouter>
</Provider>
);
};
const SuspendedApp = withTranslation()(TranslatedApp);
const App = () => (
<Suspense fallback={<Loader />}>
<SuspendedApp />
</Suspense>
)
const wrapper = document.getElementById("app");
wrapper ? ReactDOM.render(<App />, wrapper) : null;
Yes, you can. There are no restrictions on what type of Component a child component has to be to the Parent. Your only restrictions are within the component when you declare it as functional or class. Class Components and Functional Components both have their own advantages, and both should be utilized according to what your Component will do (however, it should be noted after version 16.8.0, most of the features that a Class component had prior to that version can be done with Functional Hooks, however there are still situations where Class components may serve your purpose better, like when dealing with a dynamic DOM).

React: Why isn't my context value updated?

I'm playing with React Context API. I created a simple component:
import React, { createContext, useContext } from 'react';
const MyContext = createContext(1);
const MyComponent = () => (
<>
<p>{useContext(MyContext)}</p>
<MyContext.Provider value={2}>
<p>{useContext(MyContext)}</p>
</MyContext.Provider>
</>
);
export default MyComponent;
I'm getting two <p>1</p>. Why isn't the second context updated with 2? Am I using useContext() incorrectly?
You must use a separate Component to get Context to work.
I've filed a bug about this; see https://github.com/facebook/react/issues/18629
Simply split the code using the Context into a different Component.
const Inner = () => (
<p>{useContext(MyContext)}</p>
);
const MyComponent = () => (
<>
<p>{useContext(MyContext)}</p>
<MyContext.Provider value={2}>
<Inner />
</MyContext.Provider>
</>
);
That should fix it.
You'll need to render another component inside the context provider to get the value of 2. As useContext's documentation states:
Accepts a context object (the value returned from React.createContext) and returns the current context value for that context. The current context value is determined by the value prop of the nearest <MyContext.Provider> above the calling component in the tree.
Emphasis added. The important point is that it doesn't matter where you call useContext inside the component - what matters is where that component where it's called in is located in the tree.
import React, { createContext, useContext } from "react";
const MyContext = createContext(1);
const ChildComponent = () => (
<p>{useContext(MyContext)}</p>
)
const MyComponent = () => (
<>
<p>{useContext(MyContext)}</p>
<MyContext.Provider value={2}>
<ChildComponent/>
</MyContext.Provider>
</>
);
export default MyComponent;

How to mock <AppContenxt.Consumer> in React using Jest and Enzyme

component which I'm exporting and want to test:
export default connectToStore(DefaultComponent);
connectToStore wrapper around component:
import React from 'react';
import AppContext from '../components/context/AppContext';
const connectToStore = Component => props => (
<AppContext.Consumer>
{({ state }) => (
<Component {...props} state={state} />
)}
</AppContext.Consumer>
);
export default connectToStore;
unit test calling component
it('should render view', () => {
const wrapper = render(<DefaultComponent />);
expect(wrapper.html()).toBeTruthy();
});
Error which I get:
Cannot destructure property state of 'undefined' or 'null'.
How do you test a component in general if it has a wrapper around it when being exported? How can I have the state injected hence being present in the wrapper.
Just to offer an alternative that's less complicated from a test perspective, you could have simply included a named export for the component itself as a test harness
export { DefaultComponent }
export default connectToStore(DefaultComponent)
That way your original test would still stand, you would just need to import as
import { DefaultComponent } from './defaultComponent'
And the of course when mounting mock the state prop provided by your context
const wrapper = render(<DefaultComponent state={{ ... }} />);
AppContext value property needs to be mocked:
Solution:
const wrapper = mount(
<AppContext.Provider
value={{
data,
callbackList: {}
}}
>
<DefaultComponent />
</AppContext.Provider>
);

Get Path URL with REACT

I try get the current path from my page, when I'm using react. My idea is create rules to each pages, because my application need this.
In this 1st sample, I create a component inline and works fine!
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from "react-router-dom";
const testLink = ({match}) => {
console.log(match.url)
return (<h1>Teste {match.params.username} </h1>)
}
class Sponnsor extends Component {
render() {
return (
<Router>
<Route path="/test/:username" component={testLink} />
</Router>
);
}
}
I have a correct PATH! (sample: /test/john)
But, how I'm not using like this, I could not understand how can I reproduce the {match} when I'm in the real component, like this:
import React, { Component } from 'react';
class CustomComponent extends Component {
render() {
return (
RESULT OF MY PATH
);
}
}
export default CustomComponent;
I would like, still reading the current path and after get this information I will create some condition with my code.
for instance:
localhost:3000/test/username - path should be: test/username
The match prop is only passed to the component directly specified in <Route />, so child components of TestLink must be given the match prop explicitly.
<Route path="/test/:username" component={TestLink} />
const TestLink = ({match}) => {
console.log(match.url);
// pass the `match` prop to `CustomComponent`
return <CustomComponent match={match} />;
}

React Router V4, Using render props with high order component

I'm using react router V4, when i declare a Route i want wrap my component inside a High Order component, if I use HOC in
export default hoc(Component)
Then I put the component in the render prop, it works.
When I do this
`<Route exact path="/projects" render={(props) => (withNavHOC(<ProjectsContainer {...props}/>))} />`
It returns this error:
Uncaught Error: Route.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
Why it's happening? My Hoc works fine, it returns a valid react component:
`
const withNavHOC = (WrappedComponent) => {
return class extends React.Component{
render(){
if(this.props.match.params.id){
console.log("Here");
return(
<div>
<ProjectMenu/>
<WrappedComponent {...this.props}/>
</div>)
}
return(
<div>
<Navigation/>
<WrappedComponent {...this.props}/>
</div>
)
}
}
};`
To HOC which is of course a simple function, we must pass "Component", not <Component/>.

Categories

Resources