Search code examples
cssreactjscontainersstyled-components

Passing value of input tag to a search button tag - ReactJS


Any input on how I can fix this...

My goal here is for the user to search 'Jane Smith' into the search bar, click the search button and display the cards that contain 'Jane Smith'

Currently with what I have, the user searches for 'Jane Smith' which is saved as the 'term' and once the user clicks the search button the 'fetchStudents' function fails saying it doesn't have 'term'

I'm having trouble passing a value of 'term' from SearchBarInput tag over to the SearchBarButton tag, so in the student container I can use it in the mapDispatchToProps function.

My searchBar component consists of

const SearchBar = ({ onClick, value }) => (
    <SearchBarWrapper>
        <div>
            <FontAwesomeIcon icon="search" className="searchIcon" />
            <SearchBarInput
                name="searchBarInput"
                placeholder=" Search for something..."
                label="searchBar"
                defaultValue={value}
            />
            <SearchBarButton onClick={onClick}>Search</SearchBarButton>
        </div>
    </SearchBarWrapper>
    );

    export default SearchBar;

In my student container I have

const Students = ({ studentsPayload = [], onClick }) => (
    <StudentsContainer>
        <SearchBarContainer>
            <SearchBar onClick={onClick} />
        </SearchBarContainer>
        {studentsPayload.length > 0 ? (
            <StudentsCard data={studentsPayload} />
        ) : null}
    </StudentsContainer>
);



const mapDispatchToProps = dispatch => ({ onClick: ({ target: { value } }) => dispatch(fetchStudents(value)) });


const mapStateToProps = ({ students: { studentsPayload } }) => ({ studentsPayload });
/**
 * Connects component to redux store
 */
const enhancer = connect(
    mapStateToProps,
    mapDispatchToProps,
)(StudentSearch);

export default enhancer;

My fetchStudents in actions looks like this

export const fetchStudents = term => async dispatch => {
        try {
            const { data: { items } } = await fetchData(
            `${process.env.REACT_APP_STUDENTS_URLP1}${term}${process.env.REACT_APP_STUDENTS_URLP2}`);
            dispatch({ type: FETCH_STUDENTS, studentsPayload: items });
        } catch (error) {
            throw new Error(error);
        }
    }; 

Thanks in advance!


Solution

  • Thank you for the help! I solved the problem by making the following changes :)

    In the Search bar component

    const SearchBar = ({ onClickButton, value, onValueChange }) => (
        <SearchBarWrapper>
            <div>
                <FontAwesomeIcon icon="search" className="searchIcon" />
                <SearchBarInput
                    name="searchBarInput"
                    label="searchBar"
                    placeholder="Search for something"
                    value={value}
                    onChange={onValueChange} 
                />
                <SearchBarButton onClick={() => onClickButton(value)}>Search</SearchBarButton>
            </div>
        </SearchBarWrapper>
    );
    
    export default SearchBar;
    

    In the Student container

    const Students = ({ studentsPayload = [], onClickButton }) => {
        const [value, setValue] = useState('');
        const handleChange = ({ target: { value } }) => setValue(value);
        return (
            <StudentsContainer>
                <SearchBarContainer>
                    <SearchBar
                        onClickButton={onClickButton}
                        onValueChange={handleChange}
                        value={value}
                    />
                </SearchBarContainer>
                {studentsPayload.length > 0 ? (
                    <StudentsCard data={studentsPayload} />
                ) : null}
            </StudentsContainer>
        );
    };
    
    
    const mapDispatchToProps = dispatch => ({ onClickButton: value => dispatch(fetchStudents(value)) });
    
    const mapStateToProps = ({ students: { studentsPayload } }) => ({ studentsPayload });
    /**
     * Connects component to redux store
     */
    const enhancer = connect(
        mapStateToProps,
        mapDispatchToProps,
    )(Students);
    
    export default enhancer;