SearchBar clear icon spreads a stray "key" prop into JSX, triggering a React dev warning

Đang mở Phù hợp với người mới
#4,035 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
76/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
react, react-native, typescript
Lĩnh vực
frontend, mobile-dev

Hướng nghiên cứu

Bắt đầu với src/searchbar/SearchBar-{ios,android,default}.tsx và so sánh các lệnh gọi renderNode của clear-icon với các tệp dist/searchbar đã biên dịch được hiển thị trong issue. Xóa trường key không cần thiết khỏi mỗi đối tượng props của clear-icon, sau đó xác minh rằng cả ba biến thể SearchBar đều build thành công và không còn kích hoạt cảnh báo React dev khi input không rỗng.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch react-native-elements@3.4.3 for the project I'm working on.

Problem

All three SearchBar platform variants (SearchBar-ios, SearchBar-android, SearchBar-default) render the clear ("X") button via:

renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: this.clear }))

renderNode spreads this object directly into JSX (<Icon {...defaultProps} {...content} />), and since the object includes a literal key: 'cancel' field, this triggers React's dev-mode warning on every render where the clear icon is shown (i.e. whenever the search input is non-empty):

Warning: A props object containing a "key" prop is being spread into JSX:
  let props = {key: someKey, type: ..., name: ..., size: ..., color: ..., onPress: ...};
  <Themed.Icon {...props} />
React keys must be passed directly to JSX without using spread:
  let props = {type: ..., name: ..., size: ..., color: ..., onPress: ...};
  <Themed.Icon key={someKey} {...props} />

The key field serves no purpose here — Icon isn't part of a list, and React's JSX runtime strips key out of spread props before the component ever receives it in both dev and production builds (confirmed by inspecting react-jsx-runtime.production.js), so removing it doesn't change any behavior. It only silences this dev-mode-only warning.

In our case, this warning is surfaced by Expo Go/dev-client as an in-app error banner pinned to the bottom of the screen, which intermittently overlapped a bottom-pinned navigation button in our app and caused an automated end-to-end test to fail (the button briefly failed a strict visibility/hittability check while the banner was shown).

I also checked the rewritten @rneui/base package (currently v5.0.0) and the identical bug is present there too:

renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: handleClear }))

Here is the diff that solved my problem for react-native-elements@3.4.3:

diff --git a/dist/searchbar/SearchBar-android.js b/dist/searchbar/SearchBar-android.js
index fe25d36..58514da 100644
--- a/dist/searchbar/SearchBar-android.js
+++ b/dist/searchbar/SearchBar-android.js
@@ -113,7 +113,7 @@ class SearchBar extends Component {
             ])} rightIcon={<View style={{ flexDirection: 'row' }}>
               {showLoading && (<ActivityIndicator key="loading" style={StyleSheet.flatten([{ marginRight: 5 }, loadingStyle])} {...otherLoadingProps}/>)}
               {!isEmpty &&
-                    renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: this.clear }))}
+                    renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { onPress: this.clear }))}
             </View>} rightIconContainerStyle={StyleSheet.flatten([
                 styles.rightIconContainerStyle,
                 rightIconContainerStyle,
diff --git a/dist/searchbar/SearchBar-default.js b/dist/searchbar/SearchBar-default.js
index 6df7d17..13b9a8f 100644
--- a/dist/searchbar/SearchBar-default.js
+++ b/dist/searchbar/SearchBar-default.js
@@ -112,7 +112,7 @@ class SearchBar extends React.Component {
               {showLoading && (<ActivityIndicator key="loading" style={StyleSheet.flatten([{ marginRight: 5 }, loadingStyle])} {...otherLoadingProps}/>)}
 
               {!isEmpty &&
-                    renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: this.clear }))}
+                    renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { onPress: this.clear }))}
             </View>} rightIconContainerStyle={StyleSheet.flatten([
                 styles.rightIconContainerStyle,
                 rightIconContainerStyle,
diff --git a/dist/searchbar/SearchBar-ios.js b/dist/searchbar/SearchBar-ios.js
index 145206f..b2a385d 100644
--- a/dist/searchbar/SearchBar-ios.js
+++ b/dist/searchbar/SearchBar-ios.js
@@ -115,7 +115,7 @@ class SearchBar extends Component {
             ])} placeholderTextColor={placeholderTextColor || ((_g = (_f = (_e = theme === null || theme === void 0 ? void 0 : theme.colors) === null || _e === void 0 ? void 0 : _e.platform) === null || _f === void 0 ? void 0 : _f.ios) === null || _g === void 0 ? void 0 : _g.grey)} rightIcon={<View style={{ flexDirection: 'row' }}>
               {showLoading && (<ActivityIndicator key="loading" style={StyleSheet.flatten([{ marginRight: 5 }, loadingStyle])} {...otherLoadingProps}/>)}
               {!isEmpty &&
-                    renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { key: 'cancel', onPress: this.clear }))}
+                    renderNode(Icon, clearIcon, Object.assign(Object.assign({}, defaultClearIcon(theme)), { onPress: this.clear }))}
             </View>} rightIconContainerStyle={StyleSheet.flatten([
                 styles.rightIconContainerStyle,
                 rightIconContainerStyle,

(This is the compiled dist/ output for v3.4.3; the equivalent source is src/searchbar/SearchBar-{ios,android,default}.tsx, and the same fix likely applies to packages/base/src/searchbar/ on @rneui/base.)

This issue body was partially generated by patch-package.

Ngôn ngữ chính
MDX
Star
25.9k
Fork
4.7k
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của react-native-elements/react-native-elements

Tất cả issue của react-native-elements/react-native-elements

Issue tương tự

Thêm issue về Web Dev

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.