Storybook component not show - reactjs

I setup Storybook to my project and add stories to my components. In simple components like button or Input stories appear in storybook. When i am creating stories on more advance component i cant see this component in stories. In stories i dont have any errors and i pass all args to component in story. My component looks like this:
return (
<Box>
<Paper>
{projects.map((project) => {
return project.timetracking.map((value) => {
switch (project.strategy) {
case StrategyEnum.HoursMonthly:
return (
<HoursMonthly comment={value.comment} date={value.date} hours={value.hours} />
);
case StrategyEnum.HoursDaily:
return <HoursDaily comment={value.comment} date={value.date} hours={value.hours} />;
case StrategyEnum.HoursPerTask:
return (
<HoursPerTask
comment={value.comment}
date={value.date}
hours={value.hours}
taskUrl={value.taskUrl}
/>
);
default:
return <Text>No strategy match</Text>;
}
});
})}
</Paper>
</Box>
);
};
export default TimetrackingRecords;
I write a story to this component and my story look like this:
title: 'timetracking/Records',
component: TimetrackingRecords,
} as Meta;
const Template: Story<Organization> = (args) => <TimetrackingRecords {...args} />;
export const Monthly = Template.bind({});
Monthly.args = {
id: '12jk4l12kj412rjl12jrkeqwpk',
name: 'Organizacja 1',
description: 'Nice oragnization 3, very nice',
projects: [
{
id: 'qwklkrqwlqkrlqkrw',
name: 'Project 1',
users: [
{ id: 'fdfasfasfs', email: 'test2#test.com', firstName: 'Jan', lastName: 'Kowalski' },
],
strategy: StrategyEnum.HoursMonthly,
timetracking: [
{
id: '5545dasdas54564',
hours: 3,
date: '12/12/2022',
comment: 'simple comment',
taskUrl: 'https://bebit.atlassian.net/browse/TIM-11',
},
],
},
],
users: [{ id: 'qwrlqwjrkwqjrlvn', email: 'test#test.com', firstName: 'John', lastName: 'Doe' }],
};
What i am doing wrong? Story not showing any errors. Maybe i have something wrong with configuration or Component.

Related

change the value of component with function

I am kinda new to reactjs I am using the react-dropdown library https://github.com/fraserxu/react-dropdown and I am trying to make a dropdown menu so my user can switch between 2 languages. However, I am not sure how to properly update the new value for language.
Here's my code:
const Navbar = () => {
const languages = [
{
code: 'fr',
name: 'Français',
country_code: 'fr',
key : 1
},
{
code: 'en',
name: 'English',
country_code: 'gb',
key: 2
},
]
const defaultLanguages = languages[0].name;
const changeLanguage = (e) => {
console.log(e)
}
return (
<div className={color ? 'header header-bg' : 'header'}>
<ul>
<li>
<DropDown options={languages} value={defaultLanguages} onChange={(e) => changeLanguage} />
</li>
</ul>
</div>
)
}
export default Navbar
as you can see I want to switch between french and english but I am not sure how to pass the value to the dropdown component.
You need to use the same attributes in your options (languages) passed to the Dropdown component. You can see the examples of both flag options and object options on the official repo:
//Options
//Flat Array options
const options = [
'one', 'two', 'three'
];
//Object Array options
const options = [
{ value: 'one', label: 'One' },
{ value: 'two', label: 'Two', className: 'myOptionClassName' },
{
type: 'group', name: 'group1', items: [
{ value: 'three', label: 'Three', className: 'myOptionClassName' },
{ value: 'four', label: 'Four' }
]
},
{
type: 'group', name: 'group2', items: [
{ value: 'five', label: 'Five' },
{ value: 'six', label: 'Six' }
]
}
];
Below code worked on my side:
import Dropdown from 'react-dropdown';
const Navbar = () => {
const languages = [
{
value: 'fr',
label: 'Français',
},
{
value: 'en',
label: 'English',
country_code: 'gb',
},
];
const defaultLanguages = languages[0].label;
const changeLanguage = (e) => {
console.log(e);
};
return (
<div className={'header'}>
<ul>
<li>
<Dropdown
options={languages}
value={defaultLanguages}
onChange={changeLanguage}
/>
</li>
</ul>
</div>
);
};
export default Navbar;
enter image description here
Create local state for tracking currently selected language. Also move out languages array outside of component. Here is the code:
const languages = [
{
code: 'fr',
name: 'Français',
country_code: 'fr',
key : 1
},
{
code: 'en',
name: 'English',
country_code: 'gb',
key: 2
},
]
const Navbar = () => {
const [selectedLanguage, setSelectedLanguage] = useState(languages[0].name);
const changeLanguage = (option) => {
setSelectedLanguage(option.name)
}
return (
<div className={color ? 'header header-bg' : 'header'}>
<ul>
<li>
<DropDown options={languages} value={selectedLanguage} onChange={changeLanguage} />
</li>
</ul>
</div>
)
}
export default Navbar

Minimizing un-necessary re-renders in a large list React component tree

I am creating a large list with this accordion on React Native. The problem I face is the re-renders that happening in the renderItem function. When the input changes in the Product component whole component tree is re-rendered. Is there way to stop re-rendering the whole component tree for input changes on the product component with using React.memo or React.useMemo ?
const categories = [
{ id: 1, name: 'Category A' },
{ id: 2, name: 'Category B' },
{ id: 3, name: 'Category B' },
]
const products = [
{ id: 1, name: 'Product A', category: 1 },
{ id: 2, name: 'Product B', category: 1 },
{ id: 3, name: 'Product C', category: 2 },
{ id: 4, name: 'Product D', category: 2 },
{ id: 5, name: 'Product E', category: 3 },
]
const handleChange = (product, quantity) => {
console.log('handle change event fired');
};
const renderHeader = (category) => {
return (
<View>
<Text>{category.name}</Text>
</View>
);
};
const renderContent = (category) => {
const categoryProducts = products.filter(product => product.category_id === category.id);
const renderItem = (product) => {
return (
<Product
key={product.id}
product={product}
handleChange={handleChange}
/>
);
};
return (
<View>
{
categoryProducts.map(product => {
return (renderItem(product));
})
}
</View>
);
};
return (
<ScrollView>
<Accordion
sections={categories}
renderHeader={renderHeader}
renderContent={renderContent}
/>
</ScrollView>
);
The Product Compoenent
<View>
<Input
size="small"
keyboardType="number-pad"
onChangeText={(changedQuantity) => {
handleChange( product, changedQuantity);
}}
value={quantity}
/>
</View>

Select form field not populating with options from state in ReactJS

This is my select function
import React from "react";
const Select = ({ name, label, options, error, ...rest }) => {
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<select {...rest} id={name} name={name} className="form-control">
<option value="" />
{options.map((option) => (
<option key={option.id} value={option.id}>
{option.name}
</option>
))}
</select>
{error && <div className="alert alert-danger">{error}</div>}
</div>
);
};
export default Select;
This is the component state
state = {
data: {
vat: "",
city: "",
country: "",
mobile_number: "",
address: "",
has_conference: false,
star_rating: "",
},
errors: {},
hotel_type: [],
};
This function to populate data in the hotel_type
populateHotel_Types = () => {
let hotel_type = [...this.state.hotel_type];
hotel_type = [
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
And Finally this is the render function
{this.renderSelect(
"hotel_type",
"Hotel Type",
this.state.hotel_type
)}
Render select function
renderSelect(name, label, options) {
const { data, errors } = this.state;
return (
<Select
options={options}
name={name}
value={data[name]}
label={label}
onChange={this.handleChange}
error={errors[name]}
/>
);
}
Now i am struggling to get the data populated in the renderselect function. I am quite new to react and i am actually assuming this might be a silly question therefore kindly bear with me. What could be wrong with this code. Please help. Thanks
I think in first place, you have a problem here:
populateHotel_Types = () => {
let hotel_type = [...this.state.hotel_type];
hotel_type = [
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
Here, you are filling hotel_type with your state. And below, you are redefining the array, so you will have just this 3 new objects. So should do this to have the full list:
populateHotel_Types = () => {
const hotel_type = [
...this.state.hotel_type,
{ id: "hotel", value: "hotel", name: "Hotel" },
{ id: "apartment", value: "apartment", name: "Apartment" },
{ id: "villa", value: "villa", name: "Villa" },
];
this.setState({ hotel_type });
};
I suspected this was a silly question and indeed it was. I was forgetting to run the function populateHotel_Types in the componentDidMount function. Therefore the state was not being updated appropriately. I am leaving this here so that any newbie like myself will get an answer to such a scenario

Redux not passing state to props

I connected a component to the store in a way that it's able to dispatch actions and receive state. The dispatch works and I can see the state change in the Redux dev tool. However, I'm unable to pass the state back to the component. What am I missing here?
Component
The toggle() and addTask() are successfully dispatched. However, the newTask doesn't receive the state.
class AddTask extends React.Component {
state = {
value: '',
};
setValue = value => this.setState({ value });
handleInput = () => !this.props.newTask ? 'hidden' : '';
handleToggle = () => this.props.toggle();
handleSubmit = (e) => {
e.preventDefault();
const title = this.state.value;
this.props.addTask(title);
this.props.toggle();
};
render() {
return (
<div className="add-task">
<div className="btn-add-task">
<Button
type="LINK"
label="Add a Task"
onClick={this.handleToggle}
/>
</div>
<form
className={`task-input ${this.handleInput()}`}
onSubmit={this.handleSubmit}
>
<InputField
placeholder="Task title"
value={value => this.setValue(value)}
/>
</form>
</div>
);
}
};
export default AddTask;
Container
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import AddTask from './TaskList/AddTask/AddTask';
import * as actionCreators from '../actions/taskActions';
const mapStateToProps = state => ({
newTask: state.newTask,
});
const mapDispatchToProps = dispatch => (
bindActionCreators(actionCreators, dispatch)
);
export default connect(
mapStateToProps,
mapDispatchToProps,
)(AddTask);
Reducer
import {
TOGGLE_TASK,
} from '../constants/actions';
const uiReducer = (state = {
newTask: false,
}, action) => {
switch (action.type) {
case TOGGLE_TASK:
return {
...state,
newTask: !state.newTask,
};
default:
return state;
}
};
export default uiReducer;
Store
const initialState = {
tasks: [
{
title: 'Title A', description: 'Description A', effort: '12 hrs', editing: 'false',
},
{
title: 'Title B', description: 'Description B', effort: '24 hrs', editing: 'false',
},
{
title: 'Title C', description: 'Description C', effort: '', editing: 'false',
},
],
ui: {
newTask: false,
},
};
Print
tasks: Array(4)
0: {title: "Title A", description: "Description A", effort: "12 hrs", editing: "false"}
1: {title: "Title B", description: "Description B", effort: "24 hrs", editing: "false"}
2: {title: "Title C", description: "Description C", effort: "", editing: "false"}
3: {id: "", title: "asdfasd", description: undefined}
length: 4
__proto__: Array(0)
ui:
newTask: false
Thanks!

React redux not updating component when adding to array

So no matter what I do I can't get the component to refresh when I add a item to an array in the redux store.
What I use in my reducer to add to the redux state:
case ADD_NOTE_META:
return [
...state,
action.note,
];
The connector:
import { connect } from 'react-redux';
import NoteSection from './NoteSection.component';
const mapStateToProps = state => ({
notes: state.NotesMeta,
});
const mapDispatchToProps = () => ({});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(NoteSection);
The component:
import React from 'react';
import PropTypes from 'prop-types';
import NoteSelectorContainer from './noteselector/NoteSelector.connector';
import DeleteConfirmationMessage from './deletenoteconfirmationmessage/DeleteConfirmationMessage.connector';
function NoteSection(props) {
const { notes } = props;
return (
<div id="divSelectNoteContainer">
{notes.map(item => (
<NoteSelectorContainer
note={item}
key={item.id}
/>
))}
<DeleteConfirmationMessage />
</div>
);
}
NoteSection.defaultProps = {
notes: [],
};
NoteSection.propTypes = {
notes: PropTypes.array,
};
export default NoteSection;
The state in redux is structured like:
{
NotesMeta: [
{
id: '5b6cd6c49a46d',
title: 'folder note',
tags: [
'test'
],
parentid: '5b6cd6c49a48d'
},
{
id: '5b6cd6c496ad2',
title: 'test note',
tags: [],
parentid: null
},
]
}
Output of console.log(notes) before add new note is run:
0: {id: "5b6cd6c49a46d", title: "folder note", tags: Array(1), parentid: "5b6cd6c49a48d"}
1: {id: "5b6cd6c496ad2", title: "test note", tags: Array(0), parentid: null}
After:
0: {id: "5b6cd6c49a46d", title: "folder note", tags: Array(1), parentid: "5b6cd6c49a48d"}
1: {id: "5b6cd6c496ad2", title: "test note", tags: Array(0), parentid: null}
2: {id: "5bb48aaae94c1", title: "New Note Title", tags: Array(0)}
I can see that the new note is added in both the redux store and the Notesection props however a new NoteSelectorContainer is never created.

Resources