integrate a third party component - reactjs

I'm using react-infinity as an example here. (Link to react-infinity's Readme)
After doing var Infinity = require('react-infinity'), you have access to an Infinity variable with various props.
(I presume Infinity is going to be used inside some component I create, e.g. myComponent)
This is where I am stumped. How am I supposed to use this Infinity variable?

you would use it as just another JSX component as follows...
//.....
render() {
return (
<div>
<Infinity {...props} />
</div>
);
}
//.....
where props are whatever properties the thirdparty component specs.

Related

React Context always returns EMPTY

I have a Search parent component and a SideBar child component, I am trying to get context in SideBar, but everytime it returns empty.
I followed the tutorial exactly like: https://itnext.io/manage-react-state-without-redux-a1d03403d360
but it never worked, anyone know what I did wrong?
Here is the codesandbox link to the project: https://codesandbox.io/s/vigilant-elion-3li7v
I wrote that article.
To solve your specific problem:
When using the HOC withStore you're injecting the prop store into the wrapped component: <WrappedComponent store={context}.
The value of the prop store is an object that contains 3 functions: get, set, and remove.
So, instead of printing it, you should use it. For example this.props.store.get("currentAlbums") or this.props.store.set("currentAlbums", [album1, album2]).
This example is forked by your code: https://codesandbox.io/s/nameless-wood-ycps6
However
Don't rewrite the article code, but use the library: https://www.npmjs.com/package/#spyna/react-store which is already packed, tested, and has more features.
An event better solution is to use this library: https://www.npmjs.com/package/react-context-hook. That is the new version of the one in that article.
This is an example of a sidebar that updates another component content: https://codesandbox.io/s/react-context-hook-sidebar-xxwkm
Be careful when using react context API
Using the React Context API to manage the global state of an application has some performance issues, because each time the context changes, every child component is updated.
So, I don't recommend using it for large projects.
The library https://www.npmjs.com/package/#spyna/react-store has this issue.
The library https://www.npmjs.com/package/react-context-hook does not.
You pass the store as a prop, so to access it, you need this.props.store in your SideBar.
Not this.state.store
Create a wrapping App component around Search and Sidebar:
const App = props => (
<div>
<Search />
<SideBar />
</div>
);
export default createStore(App);
Now you can manipulate state with set and get that you have available in child components Search and Sidebar.
In Search component you can have something like:
componentDidMount() {
this.props.store.set("showModal", this.state.showModal);
}
also wrapped with withStore(Search) ofc.
and in SideBar you can now call:
render() {
return (
<div>
{"Sidebar: this.state.store: ---> " +
JSON.stringify(this.props.store.get("showModal"))}
}
</div>
);
}
and you will get the output.

How to globally disable/hide/replace a component by name in React?

I have a large React app and I have a few components that I would like to completely disable from a config or global level. Is there any kind of global hook that I can use that is called before any component is rendered? If so, I imagine I can check the name of the component and return null if the name is on the disabled list. How would you do this?
There are a lot of ways to do this:
React's Context API allows you pass props through every level of the component tree so you can use them as flags to enable/disable components. Should be used sparingly however.
Higher Order Components are basically just functions that return a component. You could wrap your components in logic to render them as needed.
Or of course you could use a global state manager like redux to set global states.
There are many ways to do this, so, I'll just describe one simple way: using references and updating the states accordingly.
Full working feature hide/showing sandbox online: codesandbox.io ReactJS Feature Hide/Show Demo
Defined are two classes, class Feature extends React.Component and class App extends React.Component. The render() for <Feature/> is...
render() {
if (!this.state.enabled) {
return <div />;
}
return (
<div className="Feature">
<h1>My Feature!</h1>
</div>
);
}
And the option for enabling/disabling a feature in <App /> would handle display/hiding like so...
handleOnClick(e) {
if (e.target.checked) {
this.feature.setState({ enabled: true });
} else {
this.feature.setState({ enabled: false });
}
}
Of course, you need to make sure that <Feature /> has the reference set...
<Feature
ref={instance => {
this.feature = instance;
}}
/>
If you need simplest solution just use browser global vars and check it in render.
render() {
if( window.globalFlag ) return null
return (
<div> feature content...
Drawbacks:
modifying component,
using global scope,
some unnecessary code can be run earlier (f.e. constructor) and later (f.e. componentDidMount).
Use HOCs - wrap your component - connecting with global store using redux or context API.
<FlagsProvider store={flagStore}>
<SomeComponent_1>
<SomeComponent_2>
<FlagsConsumer flag="someFeatureFlag">
<SomeFeatureComponent />
<FlagsConsumer/> connects to store (redux connect would be an inner wrapper - composing HOCs) and conditionally renders <SomeFeatureComponent /> (or null).
Of course HOC can pass received props to wrapped component - it can be functionally transparent.
Don't reinvent the wheel - use some ready module, read tutorials, google for sth suitable.
HOC can also play a role of A/B testing.

Conditionally render list with Higher Order Component

My app has a feature toggle functionality that tells my UI whether or not a piece of UI should be rendered. I would like to create a Higher Order Component to conditionally render these types of components. In one scenario, I'm trying to conditionally render a list, but I'm running into this error:
ConditionalRender(...): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
This makes sense since I just am trying to render the children of this component. Here's what I've got so far:
https://jsfiddle.net/fmpeyton/cykmyabL/
var settings = { showHello: true, showGoodbye: false};
function ConditionalRender (props) {
var output = null;
if(props.shouldRender) output = props.children;
console.log(output);
// return (<li>{output}</li>); // This works, but isn't desired html structure
return ({output});
}
function App (props) {
return (
<ul>
<ConditionalRender shouldRender={props.settings.showHello}>
<li>Hello!</li>
</ConditionalRender>
<ConditionalRender shouldRender={props.settings.showGoodbye}>
<li>Goodbye...</li>
</ConditionalRender>
</ul>
);
}
ReactDOM.render(
<App settings={settings} />,
document.getElementById('container')
);
If I can help it, I would just like to render the children without any additional logic.This HOC would also handle more complex children down the line. Something like this:
<ConditionalRender shouldRender={props.settings.showHello}>
<div>
<p> blah blah blah</p>
<table>
<!-- ... -->
</table>
</div>
</ConditionalRender>
Any ideas?
Try this:
function App(props) {
return (
<ul>
{props.settings.showHello && <li>Hello!</li>}
{props.settings.showGoodbye && <li>Goodbye...</li>}
</ul>
);
}
P.S. Your code doesn't work because of this line:
return ({output});
Assuming you have es2015 support, it would be treated as object property shorthand. So it's the same as:
return {output: output};
which is not what React expects to get from the render method.
You could try this:
function ConditionalRender(props) {
if (props.shouldRender) {
// Make sure we have only a single child
return React.Children.only(props.children);
} else {
return null;
}
}
But this is not the simplest way. See more here.
P.P.S. Your ConditionalRender component is not what is called Higher-Order Component. According to the docs, HOC is a function that takes a component and returns a new component.

Return null from a stateless component/"functional component"

I have a stateless functional component in React 0.14 that worked in React 0.13, but now returns the following error:
No render method found on the returned component instance: you may
have forgotten to define render, returned null/false from a
stateless component, or tried to render an element whose type is a
function that isn't a React component.
This is my component:
function ToggleDisplay(props) {
//should render a <noscript> per React's implementation
if(props.if === false) {
// return <noscript></noscript>; //do I have to do this manually now?
return null;
}
let style = {};
if(shouldHide(props)) {
style.display = 'none';
}
return (
<span style={style} {...props} />
);
}
Do I have to manually return a <noscript> now? Is there another way to return null in stateless component?
As of React 15.0, you can return null from a stateless functional component. (See #5355). No more having to return <noscript /> 🎉
The change that made this possible is that React removed support for component classes that don’t inherit from React.Component, meaning they can reliably differentiate between React components (classes that inherit React.Component) and functional stateless components. So the PR to enable the functionality just involved removing and simplifying the code that instantiates the components.
Looks like not, this is a technical constraint in Javascript. To support arrow functions and plain functions as "components" React needs to know if we can call new on them.
We can call new on everything if they're plain functions as long as
they return a ReactElement. However, that won't work for
null/false/string return values and we want to support those too. We
also can't call new on arrow functions. Likewise, we can't NOT call
new on classes.
Relevant GitHub Issue

Output object name other than React with jsx syntax

with React v0.12 the #jsx pragma is gone which means it is no longer possible to output jsx with anything other than the React.METHODNAME syntax.
For my use case I am trying to wrap the React object in another object to provide some convenience methods thus, in my component files, I want to be able to write:
var myConvenienceObject = require('React-Wrapper');
var Component = myConvenienceObject.createSpecializedClass({
render: function () {
return <div />
}
})
However the jsx compiler automatially converts <div /> into React.createElement("div", null)
With older versions of React it was possible to handle this using the pragma at the top of the file. However, since that has been removed, I was wondering if there was any way currently to change the name of the object compiled by jsx so <div /> would be transformed into myConvenienceObject.createElement("div", null)
No, it's no longer possible to use a custom prefix for JSX. If you need to do this, you'll need to modify the JSX transform code, or create a fake React.
var React = require('react'), FakeReact = Object.assign({}, React, {
createElement: function(component, props, ...children){
// ...
// eventually call the real one
return React.createElement(component, props, ...children);
}
});
module.exports = FakeReact;
And then to use it you import the fake react and call it React.
var React = require('fake-react');
// ...
render: function(){ return <div />; }
If you would like to make some elements contains in your myConvenienceObject, you could consider the children props as shown in the doc. But this may need some changes in the myConvenienceObject too, to accept the children.
By the way, i'm not sure where is this createSpecializedClass functions comes from and what it does

Resources