React Convert Hooks To Class But Get Error - javascript

I want to convert react hooks component to class component but I get error.
HOOKS
import React, { useEffect, useRef } from "react";
const App = () => {
const refValt = useRef(null);
const myfuncValt = () => {
console.log("222222222222222222222");
};
useEffect(() => {
setTimeout(() => {
refValt.current.click();
}, 5000); //miliseconds
}, []);
return (
<div>
<div ref={refValt} onClick={myfuncValt}>Valt</div>
</div>
);
};
export default App;
CLASS
import React from "react";
const myfuncValt = () => {
console.log("222222222222222222222");
};
class App extends React.Component {
constructor(props) {
super(props);
const refValt = React.createRef(null);
}
componentDidMount() {
setTimeout(() => {
this.refValt.current.click();
}, 5000);
}
render() {
return (
<div>
<div ref={this.refValt} onClick={myfuncValt}>
Valt
</div>
</div>
);
}
}
export default App;
I get this error =
I try this.refValt.click(); But It doesn't working.
Actually I suspect the differences between createref vs useref.

This:
const refValt = React.createRef(null);
... needs to be this:
this.refValt = React.createRef(null);

Related

React Function: TypeError: Object(...) is not a function

I am having some issues updating my team's code in order to app the inactivity function. But when trying to do that I getting an Error message on my console
TypeError: Object(...) is not a function
If anyone knows or has an idea of what the problem really is please let me know.
Here is the console
Here is the code:
import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as Actions from '../actions';
import NeedContainer from './NeedContainer';
import ProfilContainer from './ProfilContainer';
import DealContainer from './DealContainer';
import AmountContainer from './AmountContainer';
import DurationContainer from './DurationContainer';
import MonthlyContainer from './MonthlyContainer';
import ContributionContainer from './ContributionContainer';
import FeesContainer from './FeesContainer';
import createActivityDetector from 'activity-detector'
import { useState, useEffect } from 'react';
function useIdle(time) {
const [isIdle, setIsIdle] = useState(false)
useEffect(() => {
const activityDetector = createActivityDetector(time)
activityDetector.on('idle', () => setIsIdle(true))
activityDetector.on('active', () => setIsIdle(true))
return () => activityDetector.stop()
}, [])
return isIdle;
}
class SimulatorContainer extends Component {
render() {
const isIdle = useIdle({timeToIdle:1000})
if (! this.props.ready)
return (<div className="wf-loading">Loading ...</div>);
return (
<div className={this.props.className}>
<NeedContainer />
<ProfilContainer />
<AmountContainer />
<ContributionContainer />
<DurationContainer />
<MonthlyContainer />
<DealContainer />
<FeesContainer />
</div>
);
}
}
const mapStateToProps = state => {
return {
ready:state.simulator.ready,
interest:state.simulator.interest,
}
}
const mapDispatchToProps = dispatch => {
return {
isReady: (ready) => {
dispatch(Actions.isReady(ready));
}
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(SimulatorContainer)
class useIdle extends Component() {
constructor() {
super(props)
this.state = {
isIdle: false
}
}
componentDidMount() {
this.activityDetector = createActivityDetector(time)
this.activityDetector.on('idle', () => this.setState({isIdle: true}))
this.activityDetector.on('active', () => this.setState({isIdle: true}))
}
componentWillUnmount() {
this.activityDetector.stop()
}
render(){
return this.state.isIdle;
}
}

React + Redux : Test failing with jest

I wonder why the test is failing when I use it with redux hooks:
The code is working finem but the tests are failing for some reason. I am unable to test if the component is being rendered or not.
Component:
import React, { useEffect, useState } from 'react';
import { fetchAllApis } from '../../../redux/actions/marketplace/marketplaceActions';
import { useDispatch, useSelector, connect } from 'react-redux';
import ApiCard from '../ApiCard/ApiCard';
import Spinner from '../../../components/Extras/Spinner/Spinner';
const ApiSection = ({ apiList, error, loading, categories }) => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(fetchAllApis({ page, category: categories }));
}, [dispatch, categories]);
const renderApiCards = () => {
return apiList.map((each) => (
<ApiCard key={each.apiId} info={each} data-test="ApiCard" />
));
};
if (loading) {
return <Spinner data-test="Spinner" />;
}
if (error) {
return <h1 data-test="Error">Error while fetching</h1>;
}
return (
<div className="ApiSection" data-test="ApiSection">
<div className="ApiSection__cards">{renderApiCards()}</div>
</div>
);
};
const mapStateToProps = ({ marketplaceApiState }) => {
const { apiList, error, loading } = marketplaceApiState;
return {
error,
loading,
apiList: Object.values(apiList),
};
};
export default connect(mapStateToProps)(ApiSection);
Here is the test for the above component:
Test:
import React from 'react';
import { mount } from 'enzyme';
import ApiListSection from './ApiListSection';
import { findByTestAttr, createTestStore } from '../../../../testUtils';
import { Provider } from 'react-redux';
const setup = (props = {}) => {
let initialState = {
marketPlaceState: {
apiList: {
a: { apiId: 'a', name: 'name', description: 'desc', categories: 'cat'}
},
},
};
const store = createTestStore(initialState);
const wrapper = mount(
<Provider store={store}>
<ApiListSection {...props} />
</Provider>
);
return wrapper;
};
describe('ApiListSection Component', () => {
let component;
beforeEach(() => {
component = setup();
});
// assertions
it('Should render without failing', () => {
const apiSection = findByTestAttr(component, 'ApiSection');
expect(apiSection.length).toBe(1); // <===== FAILING HERE !!!!!
});
});
I would really appreciate the help, thanks in advance

Trying to make a test for a reusable component with jest and enzyme

I've been able to set up shallow rendering tests for most of my components. This one is a reusable component with a life cycle method, so I believe I need to use mount. However the test is still failing...
this is the test
import React from 'react';
import { mount } from 'enzyme';
import SingleAdhesive from './single-adhesive';
describe('SingleAdhesive Tests', () => {
it('Renders without creashing', () => {
mount(<SingleAdhesive />)
})
});
this is the component to test
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import { getAdhesives } from '../services/adhesives';
class SingleAdhesives extends Component {
constructor(props) {
super(props);
this.state = {
adhesives: [],
selected: "",
redirect: false
}
}
componentDidMount() {
const { params } = this.props.match;
this.setState({
adhesives: getAdhesives(),
selected: params
})
}
render() {
const { adhesives, selected } = this.state;
const glue = adhesives.filter(adhesive => adhesive.name === selected.id)
return (
<div className="container m-4 p-2">
{glue.map(item =>
<div key={item.name}>
<h3>{item.name}</h3>
<div>Type: {item.type}</div>
<div>Color: {item.color}</div>
<div>Packaging: {item.packaging}</div>
<div>Shelf life: {item['shelf life']}</div>
<div>Advantages: {item.advantages}</div>
</div>
)}
</div>
);
}
}
export default SingleAdhesives;

ReactJS: How to use refs() for setting 'innerHTML' inside component?

Here I am trying to set innerHTML from my Test.js on render inside my componentDidMount. On the process I am getting errors of Unhandled Rejection (TypeError): Cannot set property 'innerHTML' of null .
I have gone through few questions where it defined to use refs() but unfotunately not able to use this in my case.
Any suggestion how can I use refs() here in my example?
demo Test.js
function updateList() {
const json = JSON.parse(localStorage["values"]);
if (json) {
picture = json.picture;
if (picture) {
userPicture = picture.name;
}
}
console.log(userPicture, "userPicture");
document.getElementById('picture').innerHTML = userPicture;
}
async function getAll () {
await updateList();
}
export default {
getAll
};
TestComponent.js
import React from 'react';
import Test from './Test';
class TestComponent extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
Test.getAll();
}
render() {
return (
<div className="test-item" >
<div className="test-picture" id="picture"> </div>
</div>
);
}
};
export default (injectIntl(TestComponent));
I believe this is what you want.
Code sandbox url - https://codesandbox.io/s/fervent-surf-n72h6?file=/src/index.js
App.component
import React from "react";
import { render } from "react-dom";
import Test from "./Test";
class App extends React.Component {
constructor(props) {
super(props);
this.divRef= React.createRef();
}
componentDidMount() {
Test.getAll(this.divRef);
}
render() {
return (
<div className="test-item">
<div className="test-picture" ref={this.divRef} id="picture">
Hello from component
</div>
</div>
);
}
}
const container = document.createElement("div");
document.body.appendChild(container);
render(<App />, container);
Test.js
function updateList(ref) {
ref.current.innerHTML = "Hello from Test.js";
}
async function getAll(ref) {
await updateList(ref);
}
export default {
getAll
};

React props function is undefined when testing

I am building a react app that deals with budgeting and I have written the code for a BillContainer component and an AddBill component.
This is my code:
BillContainer.js
import React from 'react';
import BillList from './BillList';
import AddBill from './AddBill';
class BillContainer extends React.Component {
constructor(props) {
super(props)
this.state = {
bills: [
]
}
this.addBill = this.addBill.bind(this)
}
addBill(bill) {
this.setState((state) => ({
bills: state.bills.concat([bill])
}));
}
render() {
return (
<div>
<AddBill addNew={this.addBill} />
<BillList bills={this.state.bills} />
</div>
)
}
}
export default BillContainer;
and AddBill.js
import React from 'react';
class AddBill extends React.Component {
constructor(props) {
super(props)
this.state = {
newBill: ''
};
this.updateNewBill = this.updateNewBill.bind(this)
this.handleAddNew = this.handleAddNew.bind(this)
}
updateNewBill(e) {
this.setState({
newBill: e.target.value
})
}
handleAddNew(bill) {
this.props.addNew(this.state.newBill)
this.setState({
newBill: ''
})
}
render() {
return (
<div>
<input
type='text'
value={this.state.newBill}
onChange={this.updateNewBill}
/>
<button onClick={this.handleAddNew}> Add Bill </button>
</div>
)
}
}
export default AddBill;
and this is my AddBill.test.js test:
import React from 'react';
import ReactDOM from 'react-dom';
import Enzyme from 'enzyme';
import { shallow, mount, render } from 'enzyme';
import EnzymeAdapter from 'enzyme-adapter-react-16';
import AddBill from '../components/AddBill';
let Sinon = require('sinon')
Enzyme.configure({adapter: new EnzymeAdapter() });
it('Adds a bill to the list', () => {
const clickSpy = Sinon.spy(AddBill.prototype, 'handleAddNew');
const wrapper = shallow(
<AddBill />
);
wrapper.find('button').simulate('click');
expect(clickSpy.calledOnce).toEqual(true)
})
Im trying to test that a new bill gets added when the Add Bill button is clicked. I've passed the addBill function as a prop but the test is throwing the error TypeError: this.props.AddNew is not a function.
How do I prevent the error message and and make this.props.addNew() not undefined?
You can use jest.spyOn like so:
it('Adds a bill to the list', () => {
const wrapper = shallow(
<AddBill addNew={() => {}} />
);
const clickSpy = jest.spyOn(wrapper.instance(), 'handleAddNew');
wrapper.find('button').simulate('click');
expect(clickSpy).toHaveBeenCalledTimes(1);
})
You're not passing an addNew property:
const wrapper = shallow(
<AddBill addNew={yourAddNewFunction} />
);

Categories