Я новичок в ReactJS, извините, если это звучит. У меня есть компонент, который создает несколько строк таблицы в соответствии с полученными данными.
Каждая ячейка внутри столбца имеет флажок радио. Следовательно, пользователь может выбрать один из site_name
и один address
из существующих строк. Выбор будет показан в нижнем колонтитуле. И вот где я застрял.
var SearchResult = React.createClass({
render: function(){
var resultRows = this.props.data.map(function(result){
return (
<tbody>
<tr>
<td><input type="radio" name="site_name" value={result.SITE_NAME}>{result.SITE_NAME}</input></td>
<td><input type="radio" name="address" value={result.ADDRESS}>{result.ADDRESS}</input></td>
</tr>
</tbody>
);
});
return (
<table className="table">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
{resultRows}
<tfoot>
<tr>
<td>chosen site name ???? </td>
<td>chosen address ????? </td>
</tr>
</tfoot>
</table>
);
}
});
В jQuery я мог бы сделать что-то вроде $("input[name=site_name]:checked").val()
, чтобы получить выбор одного типа флажков радио и вставить его в первую ячейку нижнего колонтитула.
Но наверняка должен быть способ Reactjs, которого я совершенно не хватает? Большое спасибо
Любые изменения в рендеринге должны быть изменены с помощью state
или props
(реакция doc).
Итак, здесь я регистрирую событие ввода, а затем изменяю state
, который затем запускает рендер, отображаемый на нижнем колонтитуле.
var SearchResult = React.createClass({
getInitialState: function () {
return {
site: '',
address: ''
};
},
onSiteChanged: function (e) {
this.setState({
site: e.currentTarget.value
});
},
onAddressChanged: function (e) {
this.setState({
address: e.currentTarget.value
});
},
render: function(){
var resultRows = this.props.data.map(function(result){
return (
<tbody>
<tr>
<td><input type="radio" name="site_name"
value={result.SITE_NAME}
checked={this.state.site === result.SITE_NAME}
onChange={this.onSiteChanged} />{result.SITE_NAME}</td>
<td><input type="radio" name="address"
value={result.ADDRESS}
checked={this.state.address === result.ADDRESS}
onChange={this.onAddressChanged} />{result.ADDRESS}</td>
</tr>
</tbody>
);
}, this);
return (
<table className="table">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
</tr>
</thead>
{resultRows}
<tfoot>
<tr>
<td>chosen site name {this.state.site} </td>
<td>chosen address {this.state.address} </td>
</tr>
</tfoot>
</table>
);
}
});
}, this);
только под </tbody>
. Что это такое и что оно делает? Я заметил без этого код вылетает.
this
контекст передается на map
функцию . Это было редактирование @FakeRainBrigand, хороший улов! Без него функция this
в карте будет ссылаться на window
, которое не имеет представления о state
Вот простейший способ реализации радиокнопки в реакции js.
class App extends React.Component {
setGender(event) {
console.log(event.target.value);
}
render() {
return (
<div onChange={this.setGender.bind(this)}>
<input type="radio" value="MALE" name="gender"/> Male
<input type="radio" value="FEMALE" name="gender"/> Female
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Edited
Вы можете использовать функцию стрелки вместо привязки. Замените вышеуказанный код как
<div onChange={event => this.setGender(event)}>
Для значения по умолчанию используйте defaultChecked
, как этот
<input type="radio" value="MALE" defaultChecked name="gender"/> Male
.bind(this)
будет создавать новую функцию каждый раз. Это означает, что когда реагируют проверки, чтобы увидеть, изменилось ли что-либо в виртуальной DOM, этот компонент всегда будет другим и всегда нуждается в повторном рендеринге.
Сделайте радио компонент как тупой компонент и передайте реквизит от родителя.
import React from "react";
const Radiocomponent = ({ value, setGender }) => (
<div onChange={setGender.bind(this)}>
<input type="radio" value="MALE" name="gender" defaultChecked={value ==="MALE"} /> Male
<input type="radio" value="FEMALE" name="gender" defaultChecked={value ==="FEMALE"}/> Female
</div>
);
export default Radiocomponent;
Основываясь на том, что React Docs говорят:
Обработка нескольких входов. Когда вам нужно обработать несколько контролируемых элементов ввода, вы можете добавить атрибут name к каждому элементу и позволить функции-обработчику выбирать, что делать, основываясь на значении event.target.name.
Например:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
handleChange = e => {
const { name, value } = e.target;
this.setState({
[name]: value
});
};
render() {
return (
<div className="radio-buttons">
Windows
<input
id="windows"
value="windows"
name="platform"
type="radio"
onChange={this.handleChange}
/>
Mac
<input
id="mac"
value="mac"
name="platform"
type="radio"
onChange={this.handleChange}
/>
Linux
<input
id="linux"
value="linux"
name="platform"
type="radio"
onChange={this.handleChange}
/>
</div>
);
}
}
Ссылка на пример: https://codesandbox.io/s/6l6v9p0qkr
Сначала ни одна из переключателей не выбрана, поэтому this.state
является пустым объектом, но всякий раз, когда выбирается this.state
получает новое свойство с именем входа и его значением. Затем легко проверить, выбрал ли пользователь какую-либо кнопку-переключатель, например:
const isSelected = this.state.platform ? true : false;
РЕДАКТИРОВАТЬ:
С версией 16.7-alpha React есть предложение для чего-то, называемого hooks
которое позволит вам делать такие вещи проще:
В приведенном ниже примере есть две группы переключателей в функциональном компоненте. Тем не менее, они контролировали входы:
function App() {
const [platformValue, plaftormInputProps] = useRadioButtons("platform");
const [genderValue, genderInputProps] = useRadioButtons("gender");
return (
<div>
<form>
<fieldset>
Windows
<input
value="windows"
checked={platformValue === "windows"}
{...plaftormInputProps}
/>
Mac
<input
value="mac"
checked={platformValue === "mac"}
{...plaftormInputProps}
/>
Linux
<input
value="linux"
checked={platformValue === "linux"}
{...plaftormInputProps}
/>
</fieldset>
<fieldset>
Male
<input
value="male"
checked={genderValue === "male"}
{...genderInputProps}
/>
Female
<input
value="female"
checked={genderValue === "female"}
{...genderInputProps}
/>
</fieldset>
</form>
</div>
);
}
function useRadioButtons(name) {
const [value, setState] = useState(null);
const handleChange = e => {
setState(e.target.value);
};
const inputProps = {
name,
type: "radio",
onChange: handleChange
};
return [value, inputProps];
}
Рабочий пример: https://codesandbox.io/s/6l6v9p0qkr
Просто идея здесь: когда речь идет о радиовводах в React, я обычно делаю их все по-другому, о чем упоминалось в предыдущих ответах.
Если это может помочь любому, кто должен отображать множество переключателей:
import React from "react"
import ReactDOM from "react-dom"
// This Component should obviously be a class if you want it to work ;)
const RadioInputs = (props) => {
/*
[[Label, associated value], ...]
*/
const inputs = [["Male", "M"], ["Female", "F"], ["Other", "O"]]
return (
<div>
{
inputs.map(([text, value], i) => (
<div key={ i }>
<input type="radio"
checked={ this.state.gender === value }
onChange={ /* You'll need an event function here */ }
value={ value } />
{ text }
</div>
))
}
</div>
)
}
ReactDOM.render(
<RadioInputs />,
document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
Я тоже запутался в радио, реализация флажка. Нам нужно, прослушать событие изменения радио, а затем установить состояние. Я сделал небольшой пример выбора пола.
/*
* A simple React component
*/
class App extends React.Component {
constructor(params) {
super(params)
// initial gender state set from props
this.state = {
gender: this.props.gender
}
this.setGender = this.setGender.bind(this)
}
setGender(e) {
this.setState({
gender: e.target.value
})
}
render() {
const {gender} = this.state
return <div>
Gender:
<div>
<input type="radio" checked={gender == "male"}
onClick={this.setGender} value="male" /> Male
<input type="radio" checked={gender == "female"}
onClick={this.setGender} value="female" /> Female
</div>
{ "Select Gender: " } {gender}
</div>;
}
}
/*
* Render the above component into the div#app
*/
ReactDOM.render(<App gender="male" />, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Нажатие на радиокнопку должно инициировать событие, которое:
self.props.selectionChanged(...)
В первом случае изменение состояния приведет к повторной визуализации, и вы можете сделать
<td>chosen site name {this.state.chosenSiteName} </td>
во втором случае, источник обратного вызова обновит все, чтобы убедиться, что в строке, ваш экземпляр SearchResult будет выбранSiteName и selectedAddress, установленный в нем реквизитами.
Чтобы построить ChinKang для ответа, у меня есть более сухой подход и в es6 для заинтересованных:
class RadioExample extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedRadio: 'public'
};
}
handleRadioChange = (event) => {
this.setState({
selectedRadio: event.currentTarget.value
})
};
render() {
return (
<div className="radio-row">
<div className="input-row">
<input
type="radio"
name="public"
value="public"
checked={this.state.selectedRadio === 'public'}
onChange={this.handleRadioChange}
/>
<label htmlFor="public">Public</label>
</div>
<div className="input-row">
<input
type="radio"
name="private"
value="private"
checked={this.state.selectedRadio === 'private'}
onChange={this.handleRadioChange}
/>
<label htmlFor="private">Private</label>
</div>
</div>
)
}
}
за исключением того, что это значение будет иметь значение по умолчанию.
input
не имеют содержимого. Поэтому<input>content</input>
не имеет смысла и недопустим. Вы можете захотеть<label><input />content</label>
.