Ref undefined in ReactJs - reactjs

When I try to use slider ref inside functionB I'm getting ref undefined error.What am i doing wrong here?
class somecomp extends Component {
constructor(props){
super(props);
this.slider = React.createRef;
}
componentDidMount(){
this.functionA();
}
functionA = () => {
functionB();
}
functionB = () => {
// When i call slider ref here im getting ref undefined
}
render() {
return (
<div ref={slider => (this.slider = slider)}></div>
);
}
}
export default somecomp;

I assume the root of your problem here
this.slider = React.createRef
You are not create ref you pass function which creates ref to slider
Try to use it in such way
this.slider = React.createRef();
Also this
<div ref={slider => (this.slider = slider)}></div>
Might be simplified to this
<div ref={this.slider}></div>
Also do not forget to user current property of ref
In your situation it will be
const node = this.slider.current;

Few problems you've in your code that should be corrected https://codesandbox.io/s/determined-lamport-gfv9j
class somecomp extends Component {
constructor(props){
super(props);
this.slider = React.createRef; // use React.createRef() at here
}
componentDidMount(){
this.functionA();
}
functionA = () => {
functionB(); // use this.functionB() at here
}
functionB = () => {
console.log("this.slider", this.slider);
// When i call slider ref here im getting ref undefined
}
render() {
return (
<div ref={slider => (this.slider = slider)}></div>
);
}
}
export default somecomp;

Related

How to passing refs to component in React

I have a data like this:
constructor(props) {
this.a = React.createRef();
this.b = React.createRef();
this.c = React.createRef();
}
setValue = (data = {}) => {
const {a='', b='', c=''} = data.constructor === ({}).constructor ? data : {};
this.a.current.setValue(a, data => {
this.b.current.setValue(data.b, data => {
this.c.current.setValue(data.c);
}
}
}
}
How could I passing that to my customized Component like this:
<CusComponent ref={this.a}>
Here is the function to get value in CusComponent:
value = function (a,b,c) {
if (arguments.length) {
if (a) {
this.setState({a}, () => {
this.value_a.value(a);
if (b) {
this.setState({b}, () => {
this.value_b.value(b);
if (c) {
this.setState({c}, () => {
this.value_c.value(c);
}
}
})
}
}
}
Thanks a lot!
Yes you can pass a ref down to a child component with:
<CusComponent ref={this.a}>
Make sure you create CusComponent with React.forwardRef because that creates an argument ref alongside props. This `ref you can directly bind to anything in your child component.
const CusComponent = React.forwardRef((props, ref) => (
<button ref={ref}>
{props.children}
</button>
));
You can read more in detail about this in the documentation.
If however both your parent and child component are class components then pass down the ref to CusComponent like so:
<CusComponent childref={this.a}>
Name the property something other than ref. Then you can access this ref in child component like below eg.
export default class CusComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return <div ref={this.props.childref}>Here</div>;
}
}

Pass original component's function to react HOC

I have created react HOC component as below.
const UpdatedComponent = (OriginalComponent) => {
class NewComponent extends React.Component {
constructor(props) {
super(props)
this.state = {
counter:0
}
}
componentDidMount(){
}
incrementCount = () => {
this.setState(prevState => {
return {counter:prevState.counter+1}
})
}
render(){
return <OriginalComponent
incrementCount={this.incrementCount}
count={this.state.counter}
/>
}
}
return NewComponent
}
export default UpdatedComponent
and I am using that component in the below example
class HoverCounter extends Component {
componentDidMount(){
}
handleMessages = () => {
// need to do somthing
}
render() {
const {incrementCount, count} = this.props
return (
<div onMouseOver={incrementCount}>
Hoverd {count} times
</div>
)
}
}
export default UpdatedComponent(HoverCounter)
I want to know that is it possible to pass
handleMessages()
function to HOC?
like this
export default UpdatedComponent(HoverCounter,handleMessages)
I have no idea how to pass the original component function or props to HOC.
you could get everyThing in your Hoc like this :
const UpdatedComponent = (OriginalComponent , func) => {
componentDidMount(){
func()
}
in HoverCounter also you could add this changes:
static handleMessages(){
// need to do something
}
export default UpdatedComponent(HoverCounter , HoverCounter.handleMessages)

Accessing child state using Refs - Cannot read property 'value' of undefined

Newbie to React:
Error
Cannot read property 'value' of undefined
This occurs after I click on one of the Cell components. I'm wanting to print this.tl.state.value to the console.
Parent Component
class App extends Component {
constructor(props) {
super(props);
this.tl = React.createRef();
}
checkForWinner = () => {
console.log("Checking for winner..." + this.tl.state.value);
}
render() {
return (
<div className="App">
<Cell ref={this.tl} winnercheck={this.checkForWinner} />
</div>
);
}
}
Child Component
class Cell extends Component {
constructor(props) {
super(props);
this.state = {
value: "X"
}
}
toggleVal = () => {
this.props.winnercheck();
}
render() {
return (
<div onClick={() => this.toggleVal()}>
{this.state.value}
</div>
);
}
}
To access the value of a ref, you need to use ref.current. In your case, that would be this.tl.current. Read the documentation for more information.

compare the first state to the last state reactjs

I am trying to make an edit page. I am update the state for any changes made. I want to compare the initial state with the last state on the last save. but I can not control the first state.
export default class extends Component {
constructor(props){
super(props);
this.changeDetails = this.changeDetails.bind(this);
this.state = {
driver: this.props.driver
}
}
changeDetails = value => {
this.setState({
driver:value
})
}
onRegister = () => {
//I want to make a comparison here.
}
render() {
const {driver} = this.state
return (
<div>
<EditView driver={driver} changeDetails={this.changeDetails}/>
</div>
);
}
}
EditView.js
export default class extends Component {
render() {
const { driver} = this.props;
const changeDetails = event => {
driver['fname] = event.target.value;
this.props.changeDetails(driver);
};
return (
<div>
<Input
value={driver.fname}
onChange={event => changeDetails(event)}
/>
</div>
);
}
}
Do not mutate driver itself directly. Use something like this:
const changeDetails = event =>
this.props.changeDetails( { ...driver, fname: event.target.value } );

How to test fetch result in componentDidMount

I need to test if the state was set after promise resolved in componentDidMount
class Todos extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
const result = todoStore.fetch();
mobx.when(
() => result.state !== mobxUtils.PENDING,
() => (this.setState({todos: result.value}))
)
}
render() {
const { todos } = this.state;
return <div>
{todos && <ul>
{todos.map(t => <li>{t.title}</li>)}
</ul>}
</div>
}
}
So far I have..
const wrapper = shallow(<Todos />);
// TODO Need wait until promise is resolved. But how?
// Maybe listen the setState method ?
// PLEASE don't use setTimout.
assert(wrapper.state('todos'))
See the full example..
https://runkit.com/ridermansb/testing-fetch-result-in-componentdidmount/1.0.0

Resources