I try get access to method of child component.
It look like that:
1.Called method by ref name of component and then method
Form.js
this.ref.details.getDataFromComponent();
<Details
pointToShow={this.state.point}
ref="details"
/>
Details.js
getDataFromComponent() {
//do my stuff get state and connect to get data for component Details
}
All the time I have "Uncaught TypeError: Cannot read property 'ref' of null"
React 15.4.2
To access refs of a component, you need to use this.refs, not this.ref.
However, this does not seem to be the issue here, as the error clearly says that this is null when you are trying to access it. To determine why this is we need to see more of your code.
You should also look into defining refs using the ref callback attribute instead of the way you are doing it, as this syntax is no longer recommended and may be removed in future releases.
As Timo has mentioned to access an element using refs you should you should write this.refs...
According to the error you don't have access to this. Most probably you are calling this.ref.details.getDataFromComponent(); inside a method without access to this
For example you write :
callRef() {
this.ref.details.getDataFromComponent();
....
}
If so then you don't have an access to this there. You should bind your function with this.
You can either use arrow function to auto bind with this :
callRef = () => {
this.ref.details.getDataFromComponent();
....
}
Note: to use arrow function you need to use babel loader in your webpack configuration.
Or you can bind when calling the method.
For example you should call callRef() method inside jsx codes like this:
< ... onClick={this.callRef.bind(this)} />
Related
I simulated my Context + DND problem in https://codesandbox.io/s/adoring-booth-33vqo . I have other components which will be added to this example and I will use a Context hook to share values across the page.
After the initial render, everything looks fine. The idea of the list is to change the order within itself and when ones changes the order with drag-drop, it throws an "Invalid Hook" error.
So the (first) real question is, what is triggering this error which is linked to the line
const { lang1Library, updateLang1Library } = useContext(LangContext)
;
Thanks in advance for your help.
Geo
It's not a good approach to provide a link for the whole project even if it is small. But I had a quick look and there's at least one thing you're doing wrong:
// DragEndFct.js
export default function DragEndFct(result, libName) {
const { lang1Library, updateLang1Library } = useContext(LangContext);
This is not React component, but it uses a hook - and it is wrong. Hooks have a special meaning in React and should be used properly (Rules of Hooks).
You can't use hooks inside regular functions and expect them to work. That is why you are getting that error.
So, there are many ways you can try to fix this. For instance, DragEndFct is a regular function, you can declare more arguments and pass stuff you get from context:
// you are using it in components right ?
function DragEndFct(result, libName, param3, param4) {}
// so you probably have access to the context there
// and can pass data from the context when you call it.
// something like this
onDragEnd={function (result) {
console.log();
DragEndFct(result, StaticVars.LANG1_LIBRARY_NAME, lang1Library, updateLang1Library);
}}
You could even make DragEndFct to be a React component - it can just return null (which means no UI will be rendered) but in that case you will have hooks and all other stuff there. It really depends on what you need and how you will use it.
I'm a bit lost learning React here.
I'm trying to get the class name of an element so I can inject an inline color depending on that class name. For example, if the element below has the class 'Active'.
<li className="active" >
I was experimenting trying to use the onChange event to see if it worked but I can't seem to fetch and print anything in the console. I assumed the event would have triggered after load and when the clase name changes, doesn't seem the case.
<li className="active" onChange={(e)=> {(console.log(e.target.className))}}
I've read a bit about React refs but it seems too much for such a simple thing. What am I missing here?
You don't need to use onChange event. You probably want to use the document object wherever you want to change the style of an element.
document.getElementsByClassName("Active")[0].style.color = '#fff';
You can use it in a function and trigger it wherever you want, or just simply put it inside useEffect hook to execute on component mount.
I have a React component using a property defined as an instance of an ES6 class with PropTypes.instanceOf(MyClass).isRequired.
When testing using an instance of a mock class, I always get a console error: Warning: Failed prop type.
I tried various techniques based on https://jestjs.io/docs/en/es6-class-mocks and https://reactjs.org/docs/testing-recipes.html , but none of them work: the type never matches what is expected (even when the class name is the same).
How would I test the component using a mock class without removing the type checking ?
It looks like I was not defining the mock class at the right place: I was defining it outside of jest.mock, but it should be defined inside, like this:
jest.mock("./MyClass", () => {
return class {
/* mock methods here */
}
});
Also, returning a function instead of a class will not work.
So simple when you know it...
I am trying to assert against an element that is provided as a prop to a component.
e.g.
function ComponentUnderTest() {
const foo = <span>đŸ‘‹</span>
return <Bob something={foo} />
}
I have tried doing something like:
shallow(<ComponentUnderTest />)
.prop(‘something’)
.matchesElement(<span>đŸ‘‹</span>)
But I get an error similar to:
(0 , _enzyme.shallow)(...).prop(...).matchesElement is not a function
It is like I need to lift the something prop value into the enzyme wrapper API.
Any ideas on how I could do this and avoid having to tap into the element itself.
Ria's comment above seems correct to me. .prop(‘something’) will return the property value for the "something" prop. This property value is not going to be a ShallowWrapper instance (you can check what it actually is by printing .prop(‘something’) to the console). Therefore, you get the normal JavaScript error you get when trying to call a function that does not exist (since .prop(‘something’).matchesElement will be undefined).
So you can wrap your prop with shallow to initialize Shallow Wrapper and assert using its methods like
shallow(
shallow(<ComponentUnderTest />).prop(‘something’)
)
.matchesElement(<span>đŸ‘‹</span>)
Is there a way to evoke a method on a chart. Such as:
chart.zoomOut()
I'm struggling to find a handle for the chart object.
To render the chart i use:
<AmCharts ref={`chart_${this.props.tileid}`} {...this.chart} dataProvider={this.props.data} />
https://github.com/amcharts/amcharts3-react
I tried to inspect the element to see if I can access these methods through:
ch = this.refs[`chart_${this.props.tileid}`]
However in the 'ch' object I can not seem to find any of the methods mentioned in:
https://docs.amcharts.com/3/javascriptcharts/AmSerialChart#zoomOut
How would one reference a element to evoke a method on it?
The amchart3-react component sets the chart as a state. Thus the method can be evoked by calling:
this.refs.chartref.state.chart.zoomOut();
You will have to talk to the maintainers of amCharts3-react. The wrapper component library could have defined the component to accept as property an event-handler that is called when the wrapper's componentDidMount method has been called, so that the event-handler can grab an instance of an object that the wrapper component is a container of.
Example:
// Note, this is just a hypothetical property. It will not actually do anything
// when applied to your code.
<AmCharts onChartRendered={chart => this._amChart = chart } {...props} />
But it seems like the author of the wrapper did not define the component to accept any such property, and therefore there isn't any way for you to invoke any methods from amCharts.