Getting setState is not defined no-undef error using React hooks - javascript

I am just getting started with React. So I generated a new React app with npx create-react-app . and it generated me a what I think is functional React hooks components. I guess this is the 2020 version.
But I ran into a problem when I tried to update my state. I basically wanted to toggle the completed property of the selected todo item. But when I called the setTodos method it gave me this error:
index.js:1 ./src/App.js
Line 27:5: 'setTodos' is not defined no-undef
import React, { useState } from 'react'
import Todos from './components/Todos.js'
function App()
{
const [todos, setTodos] = useState([
{ id: 1, title: 'First todo item', completed: false },
{ id: 2, title: 'Second todo item', completed: true },
{ id: 3, title: 'Third todo item', completed: false },
])
return (
<div>
<Todos
todos={todos}
markComplete={ (event, todo) => markComplete(event, todo) }
/>
</div>
)
}
function markComplete(event, todo)
{
// this works
console.log('You clicked todo with id: ' + todo.id + ' and title: ' + todo.title)
// setTodos is not defined...?
setTodos({
id: 1,
title: 'Test',
completed: true,
})
}
export default App

setTodos is only in scope within the function it is defined in, in this case the App component. Move markComplete into your component.
import React, { useState } from 'react'
import Todos from './components/Todos.js'
function App() {
const [todos, setTodos] = useState([
{ id: 1, title: 'First todo item', completed: false },
{ id: 2, title: 'Second todo item', completed: true },
{ id: 3, title: 'Third todo item', completed: false },
]);
function markComplete(event, todo) {
console.log('You clicked todo with id: ' + todo.id + ' and title: ' + todo.title)
setTodos({
id: 1,
title: 'Test',
completed: true,
})
}
return (
<div>
<Todos
todos={todos}
markComplete={ (event, todo) => markComplete(event, todo) }
/>
</div>
)
}
export default App

Put markComplete in the same function scope as setTodos
import React, { useState } from 'react'
import Todos from './components/Todos.js'
function App()
{
function markComplete(event, todo)
{
setTodos({
id: 1,
title: 'Test',
completed: true,
})
}
const [todos, setTodos] = useState([
{ id: 1, title: 'First todo item', completed: false },
{ id: 2, title: 'Second todo item', completed: true },
{ id: 3, title: 'Third todo item', completed: false },
])
return (
<div>
<Todos
todos={todos}
markComplete={ (event, todo) => markComplete(event, todo) }
/>
</div>
)
}
export default App

State
state use only inside a component.
state change a value inside a component.
So you must put the function markComplete inside your component App.
import React, { useState } from 'react'
import Todos from './components/Todos.js'
function App()
{
const [todos, setTodos] = useState([
{ id: 1, title: 'First todo item', completed: false },
{ id: 2, title: 'Second todo item', completed: true },
{ id: 3, title: 'Third todo item', completed: false },
])
const markComplete = (event, todo) =>
{
setTodos({
id: 1,
title: 'Test',
completed: true,
})
}
return (
<div>
<Todos
todos={todos}
markComplete={ (event, todo) => markComplete(event, todo) }
/>
</div>
)
}
export default App

Related

Display Content based on user selection

I'm developing a Yes or No question based user interface, where based on the user selection I need to load specific content and also allow users to move to previously selected question.
Below is the Data structure from which I need to load the questions.
const data = {
preQuestions: {
landingPage: {
heading: 'This is the ladning page',
buttons: {
yesButton: {
text: 'yes',
action: '1A',
},
noButton: {
text: 'No',
action: '1B',
},
},
},
'1A': {
heading: 'This is the 1A Component',
buttons: {
yesButton: {
text: 'yes',
action: '1C',
},
noButton: {
text: 'No',
action: '1D',
},
},
},
'1B': {
heading: 'This is the 1B Component',
buttons: {
yesButton: {
text: 'yes',
action: '1E',
},
noButton: {
text: 'No',
action: '1F',
},
},
},
'1C': {
heading: 'This is the 1C Component',
buttons: {
yesButton: {
text: 'yes',
action: '1G',
},
noButton: {
text: 'No',
action: '1H',
},
},
},
'1D': {
heading: 'This is the 1C Component',
buttons: {
yesButton: {
text: 'yes',
action: '1I',
},
noButton: {
text: 'No',
action: '1J',
},
},
},
},
};
Below is my logic to render the questions on user action.
const content = data.preQuestions;
const loadNextCompnent = (actionId) => {
console.log(actionId);
return renderQustionComponent(actionId);
};
const renderQustionComponent = (key) => {
console.log(content[key]);
return (
<div id={key}>
Previous question
<h1>{content[key].heading}</h1>
<button
onClick={() =>
loadNextCompnent(content[key].buttons.yesButton.action)
}
>
{content[key].buttons.yesButton.text}{' '}
</button>
<button
onClick={() => loadNextCompnent(content[key].buttons.noButton.action)}
>
{content[key].buttons.noButton.text}{' '}
</button>
</div>
);
};
Problem is, when user clicks on the yes or no button nothing happens.
How to do I move to the previous question with smooth scroll?
Below is the stackblitz link. Please guide me.
https://stackblitz.com/edit/react-ts-eugpwn?file=App.tsx
Hello i have created the following example with react-router-dom so you can have a look in the following demo:
https://react-ts-31wshc.stackblitz.io
App.tsx
import * as React from 'react';
import './style.css';
import RenderQuestionComponent from './RenderQuestionComponent';
import Test from './Test';
import Page1 from './Page1';
import { BrowserRouter, Routes, Route, useNavigate } from 'react-router-dom';
export default function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Page1 />} />
<Route path="/test" element={<Test />} />
</Routes>
</BrowserRouter>
);
}
Page1.tsx
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
export default function Page1() {
const navigate = useNavigate();
return (
<div>
<h1>THIS IS THE PAGE 1 </h1>
<button
onClick={() => {
navigate('/test'); // you will go one page back
}}
>
GO TO TEST PAGE{' '}
</button>
</div>
);
}
Test.tsx
import * as React from 'react';
import { useNavigate } from 'react-router-dom';
export default function Test() {
const navigate = useNavigate();
return (
<div>
<h1>TESTING </h1>
<button
onClick={() => {
navigate(-1); // you will go one page back
}}
>
GO BACK{' '}
</button>
</div>
);
}
You can have a look on this website to learn more about react-router-dom:
https://reactrouter.com/en/main - current version 6.4.1
Your logic for calling keys from objects are fine, the problem is that you do not have sufficient logic to update dom and see the changes. Here is the working version which I updated it with states
https://react-ts-z8clfj.stackblitz.io
import * as React from 'react';
import './style.css';
export default function App() {
const data = {
preQuestions: {
landingPage: {
heading: 'This is the ladning page',
buttons: {
yesButton: {
text: 'yes',
action: '1A',
},
noButton: {
text: 'No',
action: '1B',
},
},
},
'1A': {
heading: 'This is the 1A Component',
buttons: {
yesButton: {
text: 'yes',
action: '1C',
},
noButton: {
text: 'No',
action: '1D',
},
},
},
'1B': {
heading: 'This is the 1B Component',
buttons: {
yesButton: {
text: 'yes',
action: '1C',
},
noButton: {
text: 'No',
action: '1D',
},
},
},
'1C': {
heading: 'This is the 1C Component',
buttons: {
yesButton: {
text: 'yes',
action: '1A',
},
noButton: {
text: 'No',
action: '1B',
},
},
},
'1D': {
heading: 'This is the 1D Component',
buttons: {
yesButton: {
text: 'yes',
action: '1B',
},
noButton: {
text: 'No',
action: '1C',
},
},
},
},
};
const [active, setActive] = React.useState<any>(
data.preQuestions['landingPage']
);
const content = data.preQuestions;
const loadNextCompnent = (actionId) => {
setActive(actionId);
};
const renderQustionComponent = () => {
console.log('I am active', active);
return (
<div>
Previous question
<h1>{active?.heading}</h1>
<button
onClick={() =>
loadNextCompnent(content[active?.buttons?.yesButton?.action])
}
>
{active.buttons.yesButton.text}{' '}
</button>
<button
onClick={() =>
loadNextCompnent(content[active?.buttons?.noButton?.action])
}
>
{active.buttons.noButton.text}{' '}
</button>
</div>
);
};
return <div>{renderQustionComponent()}</div>;
}

Can not hide add-button like isEditHiden/isDeleteHiden in material table conditionally

In material-table there is option for hiding edit and delete button conditionally like
<MaterialTable
/// other props
editable={
10 > 5 && {
isEditHidden: () => !10 > 5, // This is condition
isDeleteHidden: () => !10 > 5, // This is condition
onRowAdd: newData =>
}),
onRowUpdate: (newData, oldData) =>
}),
onRowDelete: oldData =>
})
}
}
/>
if isEditHidden or isDeleteHidden is true those button hide. I want to hide add button (beside search icon) also. But i couldn't find any option. Is there any option?
You need to remove editable props and actions props for custom actions if needed and then can use hidden/disabled property to hide/disable action button.
import React from "react";
import MaterialTable from "material-table";
export default function DisableFieldEditable() {
const { useState } = React;
const [columns, setColumns] = useState([
{ title: "Name", field: "name", editable: "onUpdate" },
{ title: "Surname", field: "surname", editable: "never" },
{ title: "Birth Year", field: "birthYear", type: "numeric" },
{
title: "Birth Place",
field: "birthCity",
lookup: { 34: "İstanbul", 63: "Şanlıurfa" }
}
]);
const [data, setData] = useState([
{ name: "Mehmet", surname: "Baran", birthYear: 1987, birthCity: 63 },
{ name: "Zerya Betül", surname: "Baran", birthYear: 2017, birthCity: 34 }
]);
return (
<MaterialTable
title="Disable Field Editable Preview"
columns={columns}
data={data}
actions={[
{
icon: "add",
tooltip: "Add User",
hidden: 10 < 5,
isFreeAction: true,
onClick: (event, rowData) => {
// Perform add operation
}
},
{
icon: 'edit',
tooltip: 'Edit User',
hidden: true,
onClick: (event, rowData) => {
// Perform edit operation
}
},
{
icon: 'delete',
tooltip: 'Delete User',
disabled: true,
onClick: (event, rowData) => {
// Perform delete operation
}
}
]}
/>
);
}

How to render a material-table using a JSON that comes from a API response?

I'm new on ReactJS and this is my first page that I created, but I'm having some problems with set variables.
What I need is fill the variable table.data with the values that comes from const response = await api.get('/users') and render the table with this values when page loads.
I have the following code:
import React, { useState, useEffect } from 'react';
import { Fade } from "#material-ui/core";
import MaterialTable from 'material-table';
import { makeStyles } from '#material-ui/core/styles';
import api from '../../services/api.js';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
width: '70%',
margin: 'auto',
marginTop: 20,
boxShadow: '0px 0px 8px 0px rgba(0,0,0,0.4)'
}
}));
function User(props) {
const classes = useStyles();
const [checked, setChecked] = useState(false);
let table = {
data: [
{ name: "Patrick Mahomes", sector: "Quaterback", email: "patrick#nfl.com", tel: "1234" },
{ name: "Tom Brady", sector: "Quaterback", email: "tom#nfl.com", tel: "5678" },
{ name: "Julio Jones", sector: "Wide Receiver", email: "julio#nfl.com", tel: "9876" }
]
}
let config = {
columns: [
{ title: 'Name', field: 'name' },
{ title: 'Sector', field: 'sector' },
{ title: 'E-mail', field: 'email'},
{ title: 'Tel', field: 'tel'}
],
actions: [
{ icon: 'create', tooltip: 'Edit', onClick: (rowData) => alert('Edit')},
{ icon: 'lock', tooltip: 'Block', onClick: (rowData) => alert('Block')},
{ icon: 'delete', tooltip: 'Delete', onClick: (rowData) => alert('Delete')},
{ icon: 'visibility', tooltip: 'Access', onClick: (rowData) => alert('Access')},
{ icon: "add_box", tooltip: "Add", position: "toolbar", onClick: () => { alert('Add') } }
],
options: {
headerStyle: { color: 'rgba(0, 0, 0, 0.54)' },
actionsColumnIndex: -1,
exportButton: true,
paging: true,
pageSize: 10,
pageSizeOptions: [],
paginationType: 'normal'
},
localization: {
body: {
emptyDataSourceMessage: 'No data'
},
toolbar: {
searchTooltip: 'Search',
searchPlaceholder: 'Search',
exportTitle: 'Export'
},
pagination: {
labelRowsSelect: 'Lines',
labelDisplayedRows: '{from} to {to} for {count} itens',
firstTooltip: 'First',
previousTooltip: 'Previous',
nextTooltip: 'Next',
lastTooltip: 'Last'
},
header: {
actions: 'Actions'
}
}
}
useEffect(() => {
setChecked(prev => !prev);
async function loadUsers() {
const response = await api.get('/users');
table.data = response.data;
}
loadUsers();
}, [])
return (
<>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<Fade in={checked} style={{ transitionDelay: checked ? '300ms' : '0ms' }}>
<div className={classes.root}>
<MaterialTable editable={config.editable} options={config.options} localization={config.localization} title="Usuários" columns={config.columns} data={table.data} actions={config.actions}></MaterialTable>
</div>
</Fade>
</>
);
}
export default User;
The previous example will show 3 users that I fixed on variable table.data with 4 columns (name, sector, email, tel).
In a functional component, each render is really a new function call. So any variables you declare inside the component and destroyed and re-created. This means that table is set back to your initial value each render. Even if your useEffect is setting it correctly after the first render, it will just be reset on the next.
This is what state is for: to keep track of variables between renders. Replace your let table, with a new state hook.
const [table, setTable] = useState({
data: [
{ name: "Patrick Mahomes", sector: "Quaterback", email: "patrick#nfl.com", tel: "1234" },
{ name: "Tom Brady", sector: "Quaterback", email: "tom#nfl.com", tel: "5678" },
{ name: "Julio Jones", sector: "Wide Receiver", email: "julio#nfl.com", tel: "9876" }
]
});
Then use it like this:
useEffect(() => {
setChecked(prev => !prev);
async function loadUsers() {
const response = await api.get('/users');
setTable(prev => ({...prev, data: response.data});
}
loadUsers();
}, [])
Since table.data is not a state variable, it is regenerated as it was declared originally every time the component renders, meaning that by the time it arrives as a prop to your component it will always be the same value (when you change the value of table.data in useEffect it is too late). You need to change table.data to a state variable, and then in your useEffect hook you can update the value of table.data to the value of response.data. This will cause the component to be re-rendered but with the updated value.
Here's an example of how you might do that:
import React, { useState, useEffect } from 'react';
import { Fade } from "#material-ui/core";
import MaterialTable from 'material-table';
import { makeStyles } from '#material-ui/core/styles';
import api from '../../services/api.js';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
width: '70%',
margin: 'auto',
marginTop: 20,
boxShadow: '0px 0px 8px 0px rgba(0,0,0,0.4)'
}
}));
function User(props) {
const classes = useStyles();
const [checked, setChecked] = useState(false);
const [tableData, setTableData] = useState([]);
let config = {
columns: [
{ title: 'Name', field: 'name' },
{ title: 'Sector', field: 'sector' },
{ title: 'E-mail', field: 'email'},
{ title: 'Tel', field: 'tel'}
],
actions: [
{ icon: 'create', tooltip: 'Edit', onClick: (rowData) => alert('Edit')},
{ icon: 'lock', tooltip: 'Block', onClick: (rowData) => alert('Block')},
{ icon: 'delete', tooltip: 'Delete', onClick: (rowData) => alert('Delete')},
{ icon: 'visibility', tooltip: 'Access', onClick: (rowData) => alert('Access')},
{ icon: "add_box", tooltip: "Add", position: "toolbar", onClick: () => { alert('Add') } }
],
options: {
headerStyle: { color: 'rgba(0, 0, 0, 0.54)' },
actionsColumnIndex: -1,
exportButton: true,
paging: true,
pageSize: 10,
pageSizeOptions: [],
paginationType: 'normal'
},
localization: {
body: {
emptyDataSourceMessage: 'No data'
},
toolbar: {
searchTooltip: 'Search',
searchPlaceholder: 'Search',
exportTitle: 'Export'
},
pagination: {
labelRowsSelect: 'Lines',
labelDisplayedRows: '{from} to {to} for {count} itens',
firstTooltip: 'First',
previousTooltip: 'Previous',
nextTooltip: 'Next',
lastTooltip: 'Last'
},
header: {
actions: 'Actions'
}
}
}
useEffect(() => {
setChecked(prev => !prev);
async function loadUsers() {
const response = await api.get('/users');
setTableData(response.data);
}
loadUsers();
}, [])
return (
<>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<Fade in={checked} style={{ transitionDelay: checked ? '300ms' : '0ms' }}>
<div className={classes.root}>
<MaterialTable editable={config.editable} options={config.options} localization={config.localization} title="Usuários" columns={config.columns} data={tableData} actions={config.actions}></MaterialTable>
</div>
</Fade>
</>
);
}
export default User;

How to show the data I got from API to react-material datatable

I'm new when using materialUI table in react.js, I want to try using react-material table but I got lost as how can I show my data in the table, Let say I have 28 data and in fact it already show the right number in the pagination but the data itself doesn't show anything. this is the documentation link for react-material table Check this.
I already read several topic about this but all of them using tableRow, tableHead, and etc.
this is my component code:
import React, { Component } from 'react';
import MaterialTable from 'material-table';
import { history } from '../../../../Helpers/history';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';
import { orderActions } from '../../../../Actions/orderActions';
import { withStyles } from '#material-ui/core/styles';
// Component
import './tabledata.css';
const styles = theme => ({
'#global': {
body: {
backgroundColor: theme.palette.common.white,
},
},
});
class Tabledata extends Component {
constructor(props) {
super(props);
// const { orders } = this.props;
this.state = {
columns: [
{ title: 'Nama Pemesanan', field: 'name' },
{ title: 'Status', field: 'status' },
{ title: 'Estimasi Pengerjaan (Hari)', field: 'estimate', type: 'numeric' },
{ title: 'Jumlah Pesanan (pcs)', field: 'unit', type: 'numeric' },
{ title: 'Harga (Rp)', field: 'price', type: 'numeric' },
],
data: [
{
id: 2,
name: 'lala',
status: 'Penyablonan',
estimate: 8,
unit: 36,
price: '36.000.000',
},
],
}
}
componentDidMount() {
if(localStorage.getItem('auth')) {
const { dispatch } = this.props;
dispatch(orderActions.getAllOrder());
// history.push('/dashboard');
}
}
componentWillReceiveProps(newProps){
this.setState({ loading: newProps.loading }); // remove the loading progress when logged in or fail to log in
}
handleChange = prop => event => {
this.setState({ [prop]: event.target.value });
};
change(data){
console.log("Check ID : ", data);
}
render(){
const { orders } = this.props;
console.log("test console : ", orders)
return (
<div className="tabledata-order">
<div className="row item-section">
<div className="col">
<div className="card">
<div className="card-body">
<MaterialTable
title="Daftar Pesanan"
columns={this.state.columns}
key={orders._id}
data={orders}
/>
</div>
</div>
</div>
</div>
</div>
);
}
}
Tabledata.propTypes = {
classes: PropTypes.object.isRequired
};
const mapStateToProps = (state) => {
const { orders } = state.orderPage;
return {
orders
};
}
const connectedTableDataPage = withRouter(connect(mapStateToProps, '', '', {
pure: false
}) (withStyles(styles)(Tabledata)));
export { connectedTableDataPage as Tabledata };
As you can see, this material table have a component like this
<MaterialTable
title="Daftar Pesanan"
columns={this.state.columns}
key={orders._id}
data={orders}
/>
As you can see, in the bottom of the image you can see 1-5 of 28 and in my console there is exactly 28 data but the table itself doesn't show any data
can someone help me? how can I show the data in orders and this is the example of the image json that I have:
Finally I can fix this problem, this answer for you who have facing the same problem with react-material table if your data doesn't show but it show in console.log. you must check the field in column
this.state = {
columns: [
{ title: 'Nama Pemesanan', field: 'name' },
{ title: 'Status', field: 'status' },
{ title: 'Estimasi Pengerjaan (Hari)', field: 'estimate', type: 'numeric' },
{ title: 'Jumlah Pesanan (pcs)', field: 'unit', type: 'numeric' },
{ title: 'Harga (Rp)', field: 'price', type: 'numeric' },
],
data: [
{
id: 2,
name: 'lala',
status: 'Penyablonan',
estimate: 8,
unit: 36,
price: '36.000.000',
},
],
}
let say, json that I got have city, color, and weight then you must state the column field as such:
this.state = {
columns: [
{ title: 'detail Address', field: 'city' },
{ title: 'color', field: 'color' },
{ title: 'weight', field: 'weight' },
],
}
and for the MaterialTable you can just put all the variable you have like this
<MaterialTable
title="Daftar Pesanan"
columns={this.state.columns}
key={orders._id}
data={orders}
/>
and you can get the data like I show you below
I hope this answer can help you who have a hard time with react-material table

Test react component can't get clientWidth

I'm trying to develop unit test for my react component with jest and enzyme. So basically my component have resize listener, when resize occured my component will update component state. But i just couldn't get the clientWidth for my react component. Below is some code of my component.
import React, { Component } from "react";
import moment from "moment";
// import PropTypes from "prop-types";
import Table from "./Table";
import Grid from "./Grid";
import ActionBlock from "../ActionBlock";
import ConfirmDialog from './ConfirmDialog';
import ReactTooltip from 'react-tooltip'
import { debounce } from '../../utils';
import styles from './styles.scss';
export default class Pagination extends Component {
constructor(props) {
super(props);
this.state = {
index: props.index,
type: props.type,
config: props.config,
data: props.data,
currentPage: 1,
dataPerPage: 20,
enableActionBlock: props.enableActionBlock,
confirmDialogIndex: null,
confirmDialogActionName: null,
confirmDialogData: null,
width: 0
};
this.handleWindowResize = debounce(this.handleWindowResize.bind(this), 100); //delay trigger resize event
}
componentDidMount() {
this.setState({ width: this.refs.pagination_wrapper.clientWidth })
window.addEventListener('resize', this.handleWindowResize)
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleWindowResize);
}
handleWindowResize = () => {
this.setState({ width: this.refs.pagination_wrapper.clientWidth })
}
render() {
return (
<div ref="pagination_wrapper" className={styles.pagination_wrapper}>
<ReactTooltip />
{this.renderViewType()}
{this.renderConfirmDialog()}
</div>
)
}
}
Pagination.defaultProps = {
enableActionBlock: true,
dataPerPage: 20
};
And below is my test code.
import React from 'react'
import { shallow, mount, render } from 'enzyme';
import Pagination from '../index';
let img = 'https://www.jqueryscript.net/images/Simplest-Responsive-jQuery-Image-Lightbox-Plugin-simple-lightbox.jpg';
let imageStream = 'http://192.168.100.125:8080/';
let imgQuoteError = `http://192.168.100.71/target-data/fr/target-person-images/1111112222233333#Rizkifika-Asanuli'nam/qTD8vYa.jpeg`;
describe('Testing Pagination', () => {
let action = (actionName, indexData) => {
console.log('action APP', actionName, indexData);
}
let dataListProps = {
index: 'id',
type: 'grid',
config: [
{ text: 'Image', type: 'image', textPath: 'image', textColor: 'red', valuePath: 'image' },
{ text: 'Fullname', type: 'string', textPath: 'fullname', valuePath: 'fullname' },
{ text: 'Role', type: 'string', textPath: 'role', valuePath: 'role' },
{ text: 'Datetime', type: 'date', textPath: 'datetime', valuePath: 'datetime' },
{ text: 'Json', type: 'json', textPath: 'json', valuePath: 'json' },
],
data: [
{ id: 305, created_at: '2018-02-23T09:43:08.928Z', rule_detail: { id: 1 }, cam_detail: { id: 2, name: 'kamera huawei' }, vas_detail: { id: 3, name: 'VAS 3' }, image: img },
{ id: 306, created_at: '2018-02-23T09:43:08.928Z', rule_detail: { id: 2, name: '' }, cam_detail: { id: 3, name: 'kamera avigilon' }, vas_detail: { id: 4, name: 'VAS 4' }, image: imageStream },
{ id: 306, created_at: '2018-02-23T09:43:08.928Z', rule_detail: { id: 2, name: null }, cam_detail: { id: 3, name: 'kamera avigilon' }, vas_detail: { id: 4, name: 'VAS 4' }, image: imgQuoteError },
{ id: 306, created_at: '2018-02-23T09:43:08.928Z', rule_detail: { id: 2, name: 'Crowd Behaviour' }, cam_detail: { id: 3, name: 'kamera avigilon' }, vas_detail: { id: 4, name: 'VAS 4' }, image: imageStream },
],
onAction: action,
enableActionBlock: false
}
it('snapshot', () => {
const wrapper = shallow(<Pagination {...dataListProps}/>)
expect(wrapper).toMatchSnapshot();
})
})
I need help for solving this
As pointed by Xarvalus. If wanna access refs, the component have to be mounted first by using mount from import { shallow, mount, render } from 'enzyme';.
But it will have bug (RangeError: Invalid string length). So to overcome this, we have to convert enzyme to json by using import toJson from 'enzyme-to-json';
full working code
import React from 'react';
import { shallow, mount, render } from 'enzyme';
import toJson from 'enzyme-to-json';
import Pagination from '../index';
describe('Testing Pagination', () => {
it('snapshot', () => {
const wrapper = mount(<Pagination {...dataListProps}/>)
expect(toJson(wrapper)).toMatchSnapshot();
})
})
reference issue
You can access the window object inside your component, and so retrieve the window.innerWidth field which is, I guess, what you're looking for.

Categories

Resources