“\n\n” not being recognized from Array - javascript

I currently have a <textarea/> field that when you press enter it submits and makes a new item on the array. When you press shift + enter it creates a new line in the <textarea/> input field.
However, when you actually press shift and enter to make a new break and submit it; it does not recognize the break in the line. I have attached images below.
As you can see above, its like the array does not recognize there is a break in the input.
Todobox.jsx:
import React, { createContext } from 'react';
import Item from './Item';
import { useState, useContext } from 'react';
import '../App.css';
import trash from '../trash_can.png'
import { ElementContext } from '../ElementContext';
export const ItemContext = createContext();
export const ItemContextProvider = ({ children }) => {
const [items, setItems] = useState([]);
const [itemId, setItemId] = useState(1);
const [itemData, setItemData] = useState();
const [refDict, setRefDict] = useState({});
const newItemId = (items) =>{
setItemId(itemId + 1);
console.log(itemId)
}
const newItem = (itemChange, boxid) => {
newItemId();
if (!refDict[itemId]) {
setItems(prev => [...prev, { itemboxid: boxid, itemdata: itemChange, itemid: itemId }]);
setRefDict((prev) => ({...prev, [itemId]: true}));
}
console.log(items);
};
const value = {
items,
setItems,
newItem,
itemId
};
return(
<ItemContext.Provider value={value}>
{children}
</ItemContext.Provider>
)
};
export default function Todobox({ boxtitle, boxid }){
const { elements, setElements, newTitle } = useContext(ElementContext);
const { items, setItems, newItem } = useContext(ItemContext);
const [boxheader, setBoxHeader] = useState('');
const [itemChange, setItemChange] = useState('');
const handleChange = (e) => {
setBoxHeader(e.target.value);
}
const handleKeydown = (e) => {
if(e.keyCode == 13 && e.shiftKey == false){
setElements(elements.map(element => {
if (element.boxid === boxid) {
setBoxHeader(e.target.value)
return { ...element, boxtitle: boxheader };
} else {
return element;
}
}))
e.preventDefault();
alert('Title has been set to: ' + boxheader);
}
}
const handleDelete = (e) => {
setElements(elements.filter(element => element.boxid !== boxid))
}
const handleItemChange = (e) =>{
setItemChange(e.target.value);
}
const handleNewItem = (e) =>{
if(e.keyCode == 13 && e.shiftKey == false){
newItem(itemChange, boxid)
e.preventDefault();
e.target.value = '';
}
}
return(
<>
<div className='element-box'>
<img src={trash} className='element-box-trash' onClick={handleDelete}></img>
<textarea className='element-title-input' placeholder='Add title...' onChange={handleChange} onKeyDown={handleKeydown} value={boxheader}></textarea>
{items.map(item => {
if(item.itemboxid === boxid){
return <Item key={item.itemid} itemid={item.itemid} itemdata={item.itemdata}/>;
} else if(item.itemboxid !== boxid){
return null;
}
})}
<textarea
className='element-input'
type='text'
placeholder={`Add item... ${boxid}`}
onChange={handleItemChange}
onKeyDown={handleNewItem}
onClick={() => {console.log(boxid)}}
/>
</div>
</>
)
}
Item.jsx:
import React, { useContext } from 'react';
import '../App.css';
import { ElementContext } from '../ElementContext';
import { ItemContext } from './Todobox';
export default function Item({ itemid, itemdata }){
const { setHideModal, modals, setModals } = useContext(ElementContext);
const handleNewModal = () => {
setHideModal(false)
setModals(prev => [...prev, { modalItemId: itemid, modalId: '1', modalData: itemdata }]);
console.log(modals);
};
return(
<div className='item-container' onClick={handleNewModal}>
<a className='item-text'>{itemdata}</a>
</div>
)
}
Item-input css:
.item-text {
padding: 2px;
opacity: 1;
word-wrap: break-word;
}
Any help would be appreciated, thank you in advanced! :)

#caTS answered my question in a comment.
I had to add white-space: pre-wrap to my CSS.

Related

How to pass a function as a parameter in React?

I am trying to pass a function from a parent to child component to have the child change the parents state. Basically I have a search bar that needs to change what is displayed on the main page.
When I check the type of the function in the parent it shows up as a function but when I send and check it in the child its type is undefined. I get an error that its not a function whenever I try to call it in the child component
import LineChart from "./charts/LineChart";
import React, { Component } from 'react';
import Player from "../Components/Player";
import SearchBar from '../Components/SearchBar';
class Future extends Component {
state = {
players: [],
data: [],
playerID : ""
};
async componentDidMount() {
if (Player.playerID == "") {
const response = await fetch('http://localhost:8080/random');
const body = await response.json();
this.setState({ players: body });
console.log(body[0].player_id);
this.setState({ playerID: body[0].player_id })
this.setData(body[0].player_id)
} else {
this.displayPlayer(Player.playerID)
this.setData(Player.playerID)
}
}
async displayPlayer(playerID) {
if (playerID != "") {
const response = await fetch('http://localhost:8080/get_player/' + playerID);
const body = await response.json();
this.setState({ players: body });
}
}
onSearchChange = (value) => {
this.setState({ playerID: value });
}
async setData(id) {
const response = await fetch('http://localhost:8080/goal_prediction/' + id);
const body = await response.json();
this.setState({ data: body });
console.log(body);
}
render() {
this.displayPlayer(Player.playerID)
const { players, data, id } = this.state;
return (
<div>
<SearchBar placeholder={"Search"} stateChange={this.onSearchChange} />
{players.map(player =>
<div key={player.id}>
{player.name}'s goals
</div>
)}
<LineChart />
Goals predicted for next season: {data.predicted_goals }
</div>
);
}
}
export default Future;
import './SearchBar.css';
import React, { useState } from 'react';
import CloseIcon from '#mui/icons-material/Close';
import SearchIcon from '#mui/icons-material/Search';
import Player from '../Components/Player';
import Future from '../pages/FutureStats';
function SearchBar({ placeholder }, { stateChange }) {
const [filteredData, setFilteredData] = useState([]);
const [wordEntered, setWordEntered] = useState("");
const handleFilter = async (event) => {
const searchWord = event.target.value // Access the value inside input
setWordEntered(searchWord);
const url = 'http://localhost:8080/search_player/' + searchWord;
const response = await fetch(url);
const body = await response.json();
if (searchWord === "") {
setFilteredData([])
} else {
setFilteredData(body);
}
}
const clearInput = () => {
setFilteredData([]);
setWordEntered("");
}
const selectInput = value => () => {
console.log(Player.playerID)
Player.playerID
setFilteredData([]);
setWordEntered("");
console.log(typeof(stateChange))
stateChange(value);
}
return (
<div className='search'>
<div className='searchInputs'>
<input type={"text"} value={wordEntered} placeholder={placeholder} onChange={handleFilter} />
<div className='searchIcon'>
{filteredData.length === 0 ? <SearchIcon/> : <CloseIcon id="clearButton" onClick={clearInput} />}
</div>
</div>
{filteredData.length !== 0 && (
<div className='dataResult'>
{filteredData.slice(0, 15).map((value) => {
return (
// Stay on one page.
<a className="dataItem" target="_blank" rel="noopener noreferrer" onClick={selectInput(value.player_id)}>
<p key={value.id}>{value.name}</p>
</a>
);
})}
</div>
)}
</div>
);
}
export default SearchBar;
stateChange is part of your props and needs to be the first argument in your SearchBar function:
function SearchBar({ placeholder, stateChange }) {
...

useState defaults appear to rerun after running function on state change, defaults shouldnt run twice

I have the following issue with website where the settings state resets after running more searches. The settings component is show below in the picture, it usually works but if you uncheck a box and then run a few more searches at some point the showAllDividends setting will be set to false, the All dividends component won't be on the screen, but for some reason the checkbox itself is checked (true). This is my first time really working with checkboxes in React, and I think I'm using the onChange feature wrong. Right now I get the event.target.checked boolean, but only onChange.
If that isn't the issue then the most likely cause is the default statements being run again on another render:
const [showMainInfo, setShowMainInfo] = useState(true);
const [showYieldChange, setShowYieldChange] = useState(true);
const [showAllDividends, setShowAllDividends] = useState(true);
the thing is I don't see why the default statements would run more than once, the component isn't being destroyed there's no react router usage. I expected it to keep its current state after the page is first loaded. I think the settings defaults are being rerun, but just don't understand why they would.
I unchecked, checked, unchecked the 'All dividends' checkbox, and it was unchecked when I ran 2 more searches. After the second search the checkbox was checked but the component was gone, because showAllDividends was false
main component SearchPage.js:
import React, {useState, useEffect} from 'react';
import { connect } from 'react-redux';
import axios from 'axios';
import SearchBar from './SearchBar';
import AllDividendsDisplay from './dividend_results_display/AllDividendsDisplay';
import DividendResultsDisplay from './dividend_results_display/DividendResultsDisplay';
import SettingsView from './settings/SettingsView';
const HOST = process.env.REACT_APP_HOSTNAME
const PROTOCOL = process.env.REACT_APP_PROTOCOL
const PORT = process.env.REACT_APP_PORT
const BASE_URL = PROTOCOL + '://' + HOST + ':' + PORT
const SearchPage = ({userId}) => {
const DEFAULT_STOCK = 'ibm';
const [term, setTerm] = useState(DEFAULT_STOCK);
const [debouncedTerm, setDebouncedTerm] = useState(DEFAULT_STOCK);
const [loading, setLoading] = useState(false);
const [recentSearches, setRecentSearches] = useState([DEFAULT_STOCK]);
const [dividendsYearsBack, setDividendsYearsBack] = useState('3');
const [debouncedDividendYearsBack, setDebouncedDividendYearsBack] = useState('3');
const [errorMessage, setErrorMessage] = useState('');
const [dividendsData, setDividendsData] = useState(
{
current_price: '',
recent_dividend_rate: '',
current_yield: '',
dividend_change_1_year: '',
dividend_change_3_year: '',
dividend_change_5_year: '',
dividend_change_10_year: '',
all_dividends: [],
name: '',
description: '',
}
)
const [settingsViewVisible, setSettingsViewVisible] = useState(false);
const [showMainInfo, setShowMainInfo] = useState(true);
const [showYieldChange, setShowYieldChange] = useState(true);
const [showAllDividends, setShowAllDividends] = useState(true);
const onTermUpdate = (term) => {
setTerm(term)
}
// TODO: write a custom hook that debounces taking the term and the set debounced term callback
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedTerm(term);
}, 1500);
return () => {
clearTimeout(timerId);
};
}, [term]);
useEffect(() => {
const timerId = setTimeout(() => {
setDebouncedDividendYearsBack(dividendsYearsBack);
}, 1500);
return () => {
clearTimeout(timerId);
};
}, [dividendsYearsBack]);
useEffect(() => {runSearch()}, [debouncedTerm]);
useEffect(() => {
// alert(dividendsYearsBack)
if (dividendsYearsBack !== '') {
runSearch();
}
}, [debouncedDividendYearsBack])
useEffect(() => {
console.log("user id changed")
if (userId) {
const user_profile_api_url = BASE_URL + '/users/' + userId
axios.get(user_profile_api_url, {})
.then(response => {
const recent_searches_response = response.data.searches;
const new_recent_searches = [];
recent_searches_response.map(dict => {
new_recent_searches.push(dict.search_term)
})
setRecentSearches(new_recent_searches);
})
.catch((error) => {
console.log("error in getting user profile: ", error.message)
})
}
}, [userId])
useEffect(() => {
const user_profile_api_url = BASE_URL + '/users/' + userId
const request_data = {searches: recentSearches}
axios.post(user_profile_api_url, request_data)
// .then(response => {
// console.log(response)
// })
}, [recentSearches])
const makeSearchApiRequest = () => {
let dividends_api_url = BASE_URL + '/dividends/' + term + '/' + dividendsYearsBack
if (!recentSearches.includes(term)) {
setRecentSearches([...recentSearches, term])
}
axios.get(dividends_api_url, {})
.then(response => {
// console.log(response)
setLoading(false);
setDividendsData(response.data);
})
.catch((error) => {
console.log(error.message);
setLoading(false);
setErrorMessage(error.message);
})
}
const runSearch = () => {
console.log("running search: ", term);
setErrorMessage('');
if (term) {
setLoading(true);
if (!dividendsYearsBack) {
setDividendsYearsBack('3', () => {
makeSearchApiRequest()
});
} else {
makeSearchApiRequest()
}
}
}
const recentSearchOnClick = (term) => {
setTerm(term);
setDebouncedTerm(term);
}
const removeRecentSearchOnClick = (term) => {
const searchesWithoutThisOne = recentSearches.filter(search => search !== term)
setRecentSearches(searchesWithoutThisOne);
}
const dividendsYearsBackOnChange = (text) => {
setDividendsYearsBack(text);
}
const renderMainContent = () => {
if (!debouncedTerm) {
return (
<div className="ui active">
<div className="ui text">Search for info about a stock</div>
</div>
)
}
if (loading === true) {
return (
<div className="ui active dimmer">
<div className="ui big text loader">Loading</div>
</div>
)
}
if (errorMessage) {
return (
<div className="ui active">
<div className="ui text">{errorMessage}</div>
</div>
)
} else {
return (
<DividendResultsDisplay
data={dividendsData}
dividends_years_back={dividendsYearsBack}
dividendsYearsBackOnChange={dividendsYearsBackOnChange}
showMainInfo={showMainInfo}
showYieldChange={showYieldChange}
showAllDividends={showAllDividends}/>
)
}
}
// https://stackoverflow.com/questions/38619981/how-can-i-prevent-event-bubbling-in-nested-react-components-on-click
const renderRecentSearches = () => {
return recentSearches.map((term) => {
return (
<div key={term}>
<button
onClick={() => recentSearchOnClick(term)}
style={{marginRight: '10px'}}
>
<div>{term} </div>
</button>
<button
onClick={(event) => {event.stopPropagation(); removeRecentSearchOnClick(term)}}>
X
</button>
<br/><br/>
</div>
)
})
}
const renderSettingsView = (data) => {
if (settingsViewVisible) {
return (
<SettingsView data={data} />
)
} else {
return null;
}
}
const toggleSettingsView = () => {
setSettingsViewVisible(!settingsViewVisible);
}
const toggleDisplay = (e, setter) => {
setter(e.target.checked)
}
const SETTINGS_DATA = [
{
label: 'Main info',
id: 'main_info',
toggler: toggleDisplay,
setter: setShowMainInfo
},
{
label: 'Yield change',
id: 'yield_change',
toggler: toggleDisplay,
setter: setShowYieldChange
},
{
label: 'Dividends list',
id: 'all_dividends',
toggler: toggleDisplay,
setter: setShowAllDividends
},
]
console.log("showMainInfo: ", showMainInfo);
console.log("showYieldChange: ", showYieldChange);
console.log("showAllDividends: ", showAllDividends);
return (
<div className="ui container" style={{marginTop: '10px'}}>
<SearchBar term={term} onTermUpdate={onTermUpdate} />
{renderRecentSearches()}
<br/><br/>
<button onClick={toggleSettingsView}>Display settings</button>
{renderSettingsView(SETTINGS_DATA)}
<div className="ui segment">
{renderMainContent()}
</div>
</div>
)
}
const mapStateToProps = state => {
return { userId: state.auth.userId };
};
export default connect(
mapStateToProps
)(SearchPage);
// export default SearchPage;
the settingsView component:
import React from 'react';
import SettingsCheckbox from './SettingsCheckbox';
const SettingsView = ({data}) => {
const checkboxes = data.map((checkbox_info) => {
return (
<div key={checkbox_info.id}>
<SettingsCheckbox
id={checkbox_info.id}
label={checkbox_info.label}
toggler={checkbox_info.toggler}
setter={checkbox_info.setter}/>
<br/>
</div>
)
});
return (
<div className="ui segment">
{checkboxes}
</div>
);
}
export default SettingsView;
SettingsCheckbox.js:
import React, {useState} from 'react';
const SettingsCheckbox = ({id, label, toggler, setter}) => {
const [checked, setChecked] = useState(true)
return (
<div style={{width: '200px'}}>
<input
type="checkbox"
checked={checked}
id={id}
name={id}
value={id}
onChange={(e) => {
setChecked(!checked);
toggler(e, setter);
}} />
<label htmlFor="main_info">{label}</label><br/>
</div>
);
}
export default SettingsCheckbox;

How can I display the results of a function in React?

I would like to display in a paragraph tag the results of a function after an input. This is what I have tried:
import React, { useState } from "react";
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const checkLumens = () => {
if (brightness > 120) {
return "High";
}
if (darkness < 80) {
return "Low";
}
else {
return "Not Set";
}
};
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button>Show</button>
<p>{checkLumens()}</p> //Hide by default and show {checkLumens()} after button click
</div>
);
};
export default Measurement;
Thanks for the help!
Create a state to show and hide the lumens value using useState, and change the value on button click
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const [showLumens, setShowLumnes] = useState(false);
const checkLumens = () => {
if (brightness > 120) {
return "High";
}
if (darkness < 80) {
return "Low";
}
else {
return "Not Set";
}
};
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button onClick={()=>setShowLumnes(true)}>Show</button>
{showLumens && <p>{checkLumens()}</p>}
</div>
);
};
export default Measurement;
Just add a new state variable:
import React, { useState } from "react";
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const [showLumens, setShowLumens] = useState(false);
const checkLumens = () => {
if (brightness > 120) {
return "High";
}
if (darkness < 80) {
return "Low";
}
else {
return "Not Set";
}
};
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button onClick={() => setShowLumens(true)}>Show</button>
<p>{showLumens ? checkLumens() : null}</p> //Hide by default and show {checkLumens()} after button click
</div>
);
};
export default Measurement;
import React, { useState, useEffect } from "react";
const Measurement = () => {
const [brightness, setBrightness] = useState(0);
const [darkness, setDarkness] = useState(0);
const [lumens, setLumens] = useState('Not Set')
const [show, setShow] = useState(false)
useEffect(() => {
if (brightness > 120) {
setLumens("High");
}
if (darkness < 80) {
setLumens("Low");
}
else {
setLumens("Not Set");
}
}, [darkness, brightness])
return (
<div>
<input
type="number"
onChange={(event) => setBrightness(event.target.value)}
/>
<button onClick={() => setShow(true)}>Show</button>
<p>{show && lumens}</p> //Hide by default and show {checkLumens()} after button click
</div>
);
};
export default Measurement;

React toggle view functionality in the parent via child component

I am trying to toggle view between list of meals and meal details. I have placed a button in the child component Meal.js to the Meals.js which is meant to be the list and the details view.
Can you please help me fix this issue. Seems like its not working even with the conditional rendering method I've used in the code below.
Meal.js
import { useState } from 'react'
import './Meal.css'
const Meal = (props) => {
const [isToggled, setIsToggled] = useState(false);
const sendIdHandler = () => {
if (isToggled === true) {
setIsToggled(false);
}
else {
setIsToggled(true);
}
props.onSaveIdHandler(props.id, isToggled)
}
return (
<div
className='meal'
onClick={sendIdHandler}
>
{props.label}
</div>
);
}
export default Meal;
Meals.js
import Meal from './Meal/Meal'
const Meals = (props) => {
let toggleCondition = false;
const saveIdHandler = (data, isToggled) => {
toggleCondition = isToggled;
const mealDetails = props.mealsMenuData.findIndex(i =>
i.id === data
)
console.log(mealDetails, toggleCondition)
}
return (
<div>
{toggleCondition === false &&
props.mealsMenuData.map(item =>
<Meal
key={item.id}
id={item.id}
label={item.label}
onSaveIdHandler={saveIdHandler}
/>
)
}
{toggleCondition === true &&
<div>Horray!</div>
}
</div>
);
}
export default Meals;
UPDATE
Finally figured how to do this properly. I put the condition true/false useState in the parent instead and have Meal.js only send the id I need to view the item
Code is below..
Meals.js
import { useState } from 'react'
import Meal from './Meal/Meal'
import MealDetails from './MealDetails/MealDetails'
const Meals = (props) => {
const [show, setShow] = useState(false);
const [mealId, setMealId] = useState(0);
const saveIdHandler = (data) => {
setShow(true);
setMealId(props.mealsMenuData.findIndex(i =>
i.id === data)
)
console.log(props.mealsMenuData[mealId].ingridients)
}
const backHandler = () => {
setShow(false)
}
return (
<div>
{show === false &&
props.mealsMenuData.map(item =>
<Meal
key={item.id}
id={item.id}
label={item.label}
onSaveIdHandler={saveIdHandler}
/>
)
}
{show === true &&
<div>
<MealDetails data={props.mealsMenuData[mealId]} />
<button onClick={backHandler}>Back</button>
</div>
}
</div>
);
}
export default Meals;
Meal.js
import './Meal.css'
const Meal = (props) => {
const sendIdHandler = () => {
props.onSaveIdHandler(props.id)
}
return (
<div
className='meal'
onClick={sendIdHandler}
>
{props.label}
</div>
);
}
export default Meal;
Your problem in sendIdHandler: You can update like this:
const sendIdHandler = () => {
const newIsToggled = !isToggled;
setIsToggled(newIsToggled)
props.onSaveIdHandler(props.id, newIsToggled)
}

How to zoom a map to the selected county in react-simple-maps?

I'm new to react-simple-maps and I'm not sure how to apply the functionality of zooming to a selecting county.
Below is the parent component that contains the CovidSearchState with a useState of selected US State and selected county state.
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import MapChart from '../covid/Map';
import Spinner from 'react-bootstrap/Spinner'
import CategorySearch from '../covid/CategorySearch'
import ReactTooltip from "react-tooltip";
import { categoriesObj} from '../data/covidCategoriesName'
import CovidSearchState from '../covid/CovidSearchState'
type CovidDataState = {
fips_code: number,
State_name: string,
County: string,
Cases_7_day_count_change: number,
deaths_7_day_count_change: number,
population_density_2019: number,
avg_hh_size: number,
percent_uninsured_2019: number,
poverty_rate_2019: number,
Percent_65_plus: number,
total_hospitals_reporting: number,
admissions_covid_confirmed_last_7_days: number,
admissions_covid_confirmed_last_7_days_per_100_beds: number,
percent_adult_inpatient_beds_used_confirmed_covid: number,
percent_adult_icu_beds_used_confirmed_covid: number,
percent_positive_14_day: number,
school_composite: string
}
interface covidProps{
stateName?: string;
countyName?: string;
info?: keyof CovidDataState;
map?: boolean
}
const CovidData = (prop:covidProps) => {
const [covid, SetCovid] = useState<CovidDataState[]>([])
const [errorMessage,SetErrorMessage] = useState(null)
const [loading, setLoading] = useState(true)
const [field, setField] = useState('')
const [content, setContent] = useState("");
const [state, setState] = useState("");
const [county, setCounty] = useState("");
const [center, setCenter] = useState('')
useEffect(() => {
axios.get("https://covid-cdc-api.herokuapp.com/covid-data")
.then((response) => {
const apiCovidData = response.data.integrated_county_latest_external_data;
SetCovid(apiCovidData);
setLoading(false);
})
.catch((error) => {
SetErrorMessage(error.message);
// console.log(errorMessage);
})
}, []);
const fieldSelected = (category:string) :any => {
setField(category)
}
const stateSelected = (stateName:string) :any => {
setState(stateName)
}
const countySelected = (countyName:string) :any => {
setCounty(countyName)
}
const testing:string = "Washington"
// setCenter(testing)
if(prop.map){
return(
<div>
<CovidSearchState onStateSelected={stateSelected} onCountySelected={countySelected}/>
Select a Categories
<CategorySearch onFieldSelected={fieldSelected}/>
{loading?
<Spinner animation="border" role="status" variant="primary">
<span className="sr-only">Loading...</span>
</Spinner> : <div>
<MapChart data={covid} field={field} setTooltipContent={setContent} />
<ReactTooltip>{content}</ReactTooltip></div>}
</div>
)
}
else if (prop.countyName && prop.stateName && prop.info){
let covidData:any = covid.find(state => state.State_name === prop.stateName && state.County === prop.countyName);
if(!covidData)
return <p>Info not found!</p>
return(
<div>
{covidData[prop.info]}
</div>
)}
else {
return(
<div>Data not found!</div>
)
}
};
export default CovidData;
Below is my Map Component
import React, { memo, useState, useEffect } from "react";
import { ComposableMap, Geographies, Geography, ZoomableGroup } from "react-simple-maps";
import { scaleQuantile } from "d3-scale";
// import { csv } from "d3-fetch";
const geoUrl = "https://cdn.jsdelivr.net/npm/us-atlas#3/counties-10m.json";
const MapChart = (props) => {
const data = props.data
const field = props.field || 'Cases_7_day_count_change'
const setTooltipContent = props.setTooltipContent
const colorScale = scaleQuantile()
.domain(data.map(d => d[field]))
.range([ //change the color range here
"#ffedea",
"#ffcec5",
"#ffad9f",
"#ff8a75",
"#ff5533",
"#e2492d",
"#be3d26",
"#9a311f",
"#782618"
]);
return (
<ComposableMap data-tip="" projectionConfig={{ scale: 900 }}projection="geoAlbersUsa">
<ZoomableGroup zoom={1}>
<Geographies geography={geoUrl}>
{({ geographies }) =>
geographies.map(geo => {
const cur = data.find(s => {
return (s.fips_code == geo.id)});
return (
<Geography
key={geo.rsmKey}
geography={geo}
fill={cur ? colorScale(cur[field]) : "#EEE"}
onMouseEnter={() => {
const { name, } = geo.properties;
const id = geo.id;
setTooltipContent(
`${cur.State_name}, ${name} - ${cur[field]}
`); // cur here is our data
}}
onMouseLeave={() => {
setTooltipContent("");
}}
style={{
default: {
// fill: "#D6D6DA",
outline: "none"
},
hover: {
// fill: "#F53",
outline: "solid"
},
pressed: {
// fill: "#E42",
outline: "none"
}
}}
/>
);
})
}
</Geographies>
</ZoomableGroup>
</ComposableMap>
);
};
export default MapChart;
I think what you want is solved in this sandbox do check it out.
Code Sandbox

Categories

Resources