ReactJS Slider carousel component - reactjs

Following some code examples, I've found this:
<Slider ref = {c => (this.slider = c)} {...this.settings}>
{
//custom component for slider content
}
</Slider>
I don't get what's the meaning of ref = {c => (this.slider = c)} {...this.settings}. What is this doing? this.settings is an object with various properties, like arrows:false, mobilefirst:true. But I don't know this construct of ref etc. and in the example is not explained.
Is there a guide for this?

This code creates reference to the element to work with it later - it is stored on the class and can be accessed with this.slider or passed down as a prop to children. For example, it can be used to set focus just like with regular HTML element: this.slider.focus(). You can read more about callback refs here: https://reactjs.org/docs/refs-and-the-dom.html#callback-refs

Related

How to render dom element based on value of passed prop?

I am working on a Text component that has a prop as, this can be any valid text dom element i.e. <Text as="p" /> or <Text as="h1" />. Within component itself I want to render respective dom element and thus far I ended up with a big switch statement for this, however I am wondering if there is a better approach that is less verbose?
I tried looking at ui libs like chakra and material ui that have same patter, but quiet frankly wasn't able to figure it out form there.
I would then have an object store it somewhere outside of your component like in constants called e.g htmlOptionTag there you can have every expected props "as" :
const htmlOptionTag = {
"a": ({label, ...rest}) => <a {...rest}>{label}</a>,
"div": ({text, ...rest}) => <div {...rest}>{text}</div>,
.....
};
Then import and use it inside Text component :
return htmlOptionTag[as](props) || null;
I created a function domElement and it accepts two parameters :
tag and their attributes.
/**
* #param {*} tag "a"
* #param {*} attr {"href":"https://example.com", "class":"custom-class"}
* #returns
*/
const domElement = (tag, attr)=>{
let ele = document.createElement(tag);
if(Object.keys(attr).length > 0){
for(let i in attr){
ele.setAttribute(i,attr[i]);
}
}
return ele;
}
Now if you run domElement("a", {"href":"https://example.com", "class":"custom-class"})
It will return :
Note : You can also pass function as {"onclick" : ()=>{console.log("I am a function")}}
You can also tweak my answer to ReactJS specific. I don't have much time right now, so I just gave you a hint on how you can minimize your code without having ifelse or switch statements.
After playing with this I discovered that react has React.createElement function that takes in dom element strings like a or h1 for example, so to achieve my goals all I had to do was
return React.createElement('a', otherProps)

react-jsx-highcharts with functional component and formatter

I am testing the react-jsx-highcharts possibilities with a polar chart.
Versions:
React: 17.0.1
react-jsx-highcharts: 4.2.0
typescript: 4.0.3
I am using the functional components. So, I don't have any "class" nor "this" in my code.
The chart code is :
<HighchartsProvider Highcharts={Highcharts}>
<HighchartsChart polar plotOptions={plotOptions}>
<Tooltip shared
formatter={tooltipFormatter}
/>
...
</HighchartsChart>
</HighchartsProvider>
All the examples that I have found use this.x, this.value to generate a rich formatter.
For example here or here
I have tried to use the explicit type as:
const tooltipFormatter:TooltipFormatterCallbackFunction = (mycontext: TooltipFormatterContextObject, mytooltip: Tooltip) => {
return "...";
}
but typescript does not accept it, and I cannot find a way to build a clear rich formatter.
Thank you!
I found the solution in their documentation: https://www.npmjs.com/package/react-jsx-highcharts
, where it mentioned, in "Exception 1":
Where Highcharts events are concerned - instead of passing events as an object, we use the React convention onEventName.
So we can use the callback props in <HighchartsChart> element to get the chart object, like so:
const [chart, setChart] = useState({});
const setChart = cha => {
setChart(cha);
}
...
<HighchartsProvider Highcharts={ Highcharts }>
<HighchartsChart plotOptions={ plotOptions } chart={ chartOptions } callback={ setChart }>
...
And we can access the chart object with the chart state.

Passing an array of Components as a Props in React

I am looking for a way to pass an array of components to a prop for a tabbing component. Just wondering if that's possible.
So I need to create a component that will shorten material ui's tabbing method but I cannot find a way to pass an array of components as a prop so that it will be rendered on that component.
Here is an example of my code:
<FullWidthTab
components = [<Component1/>, <Component2/>] //this is where components renders
menuLabels = ['Menu1', 'Menu2'] //this is where title render
/>
And I map them on my code like this and I used lodash map method:
map(components, component=>{
<TabContainer>{component}</TabContainer>
}
But it returns this.
Warning: react-swipeable-view: one of the children provided is invalid: null.
We are expecting a valid React Element
And when I console.log the component it returns:
{$$typeof: Symbol(react.element), type: ƒ, key: null, ref: null, props: {…}} Object Need help
I hope it can render the components.
Component's name must be started with a capital letter, but I can see here components = [<component1/>, <component2/>] they were not. So you must convert [<component1/>, <component2/>] to [<Component1/>, <Component2/>]. Second thing I see your map syntax is strange, it must be like this:
components.map(component => (<TabContainer>{component}</TabContainer>))
Reference: https://reactjs.org/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized
I solved This with another implementation.
I used 'react-swipeable-views' and instead passing a component I used this
<SwipeableViews
axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}
index={this.state.value}
onChangeIndex={this.handleChangeIndex}
>
{ children }
</SwipeableViews>
And Changed:
<FullWidthTab
components = [<Component1/>, <Component2/>] //this is where components renders
menuLabels = ['Menu1', 'Menu2'] //this is where title render
/>
To
<FullWidthTab
components = [<Component1/>, <Component2/>] //this is where components renders
menuLabels = ['Menu1', 'Menu2'] //this is where title render
>
<Component1/>
<Component2/>
</FullWidthTab>
But if you can get how to pass components via props that would be great!
Cause you need return a value in map.
map(components, component=>{
return <TabContainer>{component}</TabContainer>
}
Your es6 syntax needs a subtle adjustment to return the react component.
map(components, component => <TabContainer>{component}</TabContainer> )
or, if you can use the map function from your array instead of importing from a library.
components.map( component => <TabContainer>{component}</TabContainer> )

How to get the selected text from text area in react?

I am trying to make a text editor in react.Does anyone knows how to get the selected text from the textarea so that styles can be applied on the selected text.I know we can use window.getSelection in javascript but I am curious to know If any other methods are available for this functionality?
Yes there is a method to do this, specially in React. The way you should go to achieve this is as follow.
step 1:- use ref in your textarea ui element. like
`<textarea
className='html-editor'
ref='myTextarea'
value = {this.state.textareaVal}
onChange={(event)=>{
this.setState({
textareaVal:event.target.value;
});
}}
>
</textarea>`
step 2:- now you can access the DOM element,using react refs.
let textVal = this.refs.myTextarea;
step 3:- use selectionStart and selectionEnd :- using selectionStart and
selectionEnd you can get to know your start and end pointer
of selected text.which can be done as below;
let cursorStart = textVal.selectionStart;
let cursorEnd = textVal.selectionEnd;
now you have start and end index of your selected text.
step 4 :- use javascript substring function to get the selected text.
this.state.textareaVal.substring(cursorStart,cursorEnd)
The best way to make a Text Editor in React is to use DraftJS.
If you are using React, DraftJS is the way to go about it. It abstracts away many of the challenges you would face while trying to create your own text editor from scratch. This includes managing the state of your editor (similarly to how you would manage a component's state), managing text selection, applying different attributes and so on.
You can get started by checking out the docs, and I would suggest watching the introduction video on that page, which goes through the difficulties DraftJS aims to solve.
I hope that helps.
How to do it in functional component? Expanding on the answer given by Sanjeev.
function MyEditor() {
const [state,setValue] = useState({value: ""});
//1
const myRef = React.createRef()
const inputsHandler = (e) =>{
var taxt = e.target.innerHTML
let textArray = taxt.split(/\n/gm)
console.log(textArray)
setValue( {value: e.target.value} )
}
const onDone = () => {
console.log("on done", stateNew)
dispatch(updateEditorVisibility())
// dispatch(props.reducer(state.value))
dispatch(stateNew.editorReducerAction(state.value))
}
return (
<div>
<textarea
type="text"
ref={myRef}
name="first_name"
onChange={inputsHandler}
value={state.value}/>
<button onClick={() => {
let textVal = myRef.current;
let cursorStart = textVal.selectionStart;
let cursorEnd = textVal.selectionEnd;
let selectedText = state.value.substring(cursorStart,cursorEnd)
console.log(selectedText)
}}>Log</button>
</div>
)}
Create a ref using create ref
const myRef = React.createRef();
set the ref in your textarea
ref={myRef}
To access use
let cursorStart = textVal.selectionStart;
let cursorEnd = textVal.selectionEnd;
let selectedText = state.value.substring(cursorStart,cursorEnd)
console.log(selectedText)````

React - how to do jQuery style find() to find children of a DOM node?

I've got a component that returns this:
return (
<div className="audio-widget">
<div
className={this.props.className}
onWheel={this.handleWheel}
/>
{controls}
</div>
)
I need to do the equivalent of:
handleWheel(event) {
let $canvas = $('.audio-widget').find('canvas');
[...]
}
The canvas is drawn programatically by a 3rd party script, so I can't just slap an ID on it (especially since this is a component and there are several per page).
Excuse the extreme n00b question, I'm brand new to React. Thanks!
This is a good use case for the ref prop. If you give a component a ref prop, e.g. ref="foo", upon rendering that component will be available as e.g. this.refs.foo. Then you can get the rendered DOM node with React.findDOMNode.
render() {
// ...
return (
<div ref="audioWidget" className="audio-widget">
<div
className={this.props.className}
onWheel={this.handleWheel}
/>
{controls}
</div>
);
}
handleWheel(event) {
let canvas = React.findDOMNode(this.refs.audioWidget)
.querySelector('canvas');
// ...
}
You can learn more about refs here: https://facebook.github.io/react/docs/more-about-refs.html
I think, it's a bad way to direct access 'canvas' with selector, the reason is as follows:
When you component changed, the React will do some diff works, then update your dom with a best way, that means, the node you get with selector may be changed to another node just for 'the best way'.
You can build a 'Child Component', and do something in the 'handleWheel' of the 'Parent Component', then communicate with the 'Child Component' through the 'props' for 'Child Component'

Resources